Orchestrata Ultimate › Plans › spec-audit › reverify-2026-10-18 › D-providers-llm
Cluster D — Providers & LLM — re-verification (2026-10-18)
Source: plans/spec-audit/reverify-2026-10-18/D-providers-llm.md at 8a2cb42ad · last changed 2026-10-18 · first committed 2026-10-18 · 284 lines.
Prose pending.
Plan text
Cluster D — Providers & LLM — re-verification (2026-10-18)
Re-verification of src/orchestrata_ultimate/ against 4 specs on branch components
(337 commits ahead of the 2026-07-14 audits). Method per _METHOD.md + the re-verify brief:
AST toolkit only for Python structure; .pl Prolog grep for governance predicates; .md
specs read directly. Prior work confirmed/updated against docs/spec-gap-register.md and
plans/spec-audit/D-providers-llm.md (session 195).
Trusted main-session verdicts (NOT re-verified): SPEC-028 FR-009 env-override divergence
RESOLVED (spec updated); SPEC-011 FR-015 real TiktokenCounter landed. Both re-confirmed
incidentally as present (see below) but not re-litigated.
SPEC-011 Provider Manager — PARTIAL
-
Specifies: unified LLM provider abstraction — routing, fallback, circuit breaker, rate limiting, cost tracking, budget enforcement, PAM++ governance, Neo4j audit trail, EventBus events.
-
Verified:
- ✅ FR-001 interface + lifecycle.
ProviderManagerProtocol(core/protocols/providers.py:241, inheritsComponentProtocol),ProviderManager(providers/provider_manager.py:75) implements it;initialize/start/stop/get_health(:123/:143/:150/:175);ComponentMetadatacarriescomponent_type=ComponentType.PROVIDER_MANAGER(:104). Wired —refs ProviderManager→ 13 USE sites inllm/client.py(e.g.:371/:405/:482/:504). ⚠️ DI-registration is a lazy module-level singleton inllm/client.py:482(_get_provider_manager), NOT aDIContainerresolution — consistent with the D1 orphan-DI-container decision, not a functional hole. - ✅ FR-002 execute / FR-004 estimate / FR-016 cancel.
execute(:258),estimate_cost(:453),get_usage(:472),get_remaining_budget(:489),cancel(:502),get_provider_health(:512)._invoke_provider(:348) registers the in-flight task (self._in_flight[request.request_id] = complete_task,:361) socancel/stopcan interrupt it — FR-016 is wired, not a stub. - ✅ FR-003 routing / FR-008 fallback / FR-009 breaker / FR-010 limiter.
RequestRouter.route/get_fallback_chain(router.py:55/:88); fallback loop inexecute(:274-307);CircuitBreaker(circuit_breaker.py:47, defaultsfailure_threshold=5,cooldown_seconds=60,success_threshold=3— matches spec FR-009);RateLimiter(rate_limiter.py:25,rpm_limit=60,tpm_limit=100000,headroom_pct/has_low_headroom). - ✅ FR-006 model registry.
ProviderRegistry(registry.py:22) withresolve_model(alias,:80),find_by_capability(:85),get_pricing(:72),model_count(:108). - ✅ FR-007 adapters.
ProviderProtocol(core/protocols/providers.py:217,complete/get_models/supports_capability);BaseAdapter(adapters/base.py:44); 7 concrete adapters —anthropic,claude_cli,deepseek,ollama,openai,openrouter(all underproviders/adapters/). - ✅ FR-011 cost tracking / FR-012 budget enforcement.
CostTracker(cost_tracker.py:71, Redis-backed):calculate_cost(:95),record_cost(:128, aggregates volk/session/project + canonical budget key),check_budget(:106, TOCTOU-safe Luaevalsha),get_usage(:186),get_remaining_budget(:217). Enforcement wired via_enforce_budget(provider_manager.py:312) before dispatch. - ✅ US-007 health monitoring.
HealthMonitor(health_monitor.py:28, sliding-window latency/error/percentiles,_percentile:98), fed by_record_success/_record_failure(provider_manager.py:370/:416). - ✅ FR-015 token counting (trusted, re-confirmed present):
_token_counter_for(provider_manager.py:532, memoisedTiktokenCounter, OpenAI-family→exact encoding, others→gpt-4/cl100k_base) →_estimate_cost_for_pricing(:554) →estimate_cost/_enforce_budget. - ⚠️ FR-005 config source — DIVERGENT. Providers are registered in code by
llm/client.py_register_claude_cli/_register_anthropic/_register_deepseek/_register_openai/_register_openrouter/_register_ollama(:404-446) reading env keys, not fromconfigs/production.yamlwith${API_KEY}interpolation. Functionally complete; mechanism differs from spec. - ❌ FR-013 PAM++ Prolog governance — ABSENT.
execute()(:258-311) performs no model-access governance check;provider_manager.pyimports no governance/janus module.grep -rn 'allowed_model|within_budget|can_use_provider|budget_override|model_allowlist|model_denylist|volk_budget_limit' src/orchestrata_ultimate/prolog/→ 0 hits (all 33.plfiles). No allowlist/denylist/budget predicates exist. - ❌ FR-014 Neo4j audit trail — ABSENT.
CostTrackeris Redis-only (cost_tracker.py:1-241, prefixorchestrata:provider:cost); no Neo4j import, no(:ProviderAudit)/(:CostRecord)/(:ProviderHealth)nodes, no cold migration.symbols ProviderAudit|ProviderHealth→ onlycore/protocols/providers.py:58 CostRecord(the dataclass). - ❌ Event delivery — ABSENT.
initialize(:123-140) subscribes to nothing; nokernel.emit_event/event_bus.subscribeimport anywhere inproviders/; none of the spec's 9 topics (provider.request.completed,provider.fallback.triggered,provider.budget.warning, …) is emitted. FR-012 budget-warning events (80/90/95%) also not emitted.
- ✅ FR-001 interface + lifecycle.
-
Remaining work / plan:
- Scope: (a) FR-013 Prolog model-access + budget-governance gate in
execute()before dispatch; (b) FR-014 Neo4jProviderAudit/CostRecord/ProviderHealthpersistence + hot→cold migration onsession.closed; (c) EventBus emission of provider lifecycle/budget/fallback events + reactive subscriptions tovolk.lifecycle.terminated/session.closed. FR-005 YAML config is a smaller divergence (adoptproduction.yamlloading or update the spec to code-driven registration). - Target files:
providers/provider_manager.py(governance hook inexecute/_enforce_budget; event emission);providers/cost_tracker.py(Neo4j cold-store + session-close migration); a newproviders/governance.py(janus predicate calls); governance.plrule additions; EventBus wiring. - Approach: add a governance gate calling the janus adapter (ground facts asserted, variable rules in
.pl) inexecute(); emitSystemEvents viakernel.emit_eventat completion/failure/fallback/budget thresholds; persist audit nodes to Neo4j and subscribe amigrate_to_cold-style hook tosession.closed. - Dependencies: Prolog-janus governance (SPEC-013 PAM++), kernel EventBus (SPEC-001), Neo4j persistence +
session.closedwiring — the same unwiredsession.closeddecision that blocks SPEC-010 FR-008. - Effort: L. Risk: med — governance-in-hot-path couples to janus + EventBus lifecycle and adds latency (NFR-001 <5ms); audit persistence is additive but needs the persistent-engine wiring.
- Scope: (a) FR-013 Prolog model-access + budget-governance gate in
-
Evidence log:
symbols ProviderManager→ classprovider_manager.py:75;refs ProviderManager→ 13 USE inllm/client.py.source providers.provider_manager(full read):execute:258, no governance call, no event emission;initialize:123subscribes to nothing;_invoke_provider:361tracks_in_flight.source providers.cost_tracker→ Redis-only, Lua budget script, no Neo4j.symbols CircuitBreaker|RateLimiter|RequestRouter|HealthMonitor|ProviderRegistry|CostTracker→ all present.grep -rn 'allowed_model|within_budget|can_use_provider|budget_override|...' src/orchestrata_ultimate/prolog/→ 0 hits.symbols ProviderAudit|ProviderHealth→ 0 insrc/(only theCostRecorddataclass atprotocols/providers.py:58).
SPEC-025 Code Generation Drivers — DONE (FR-006 divergence)
-
Specifies: a uniform async
AsyncCodeDriverProtocol over 7 code-gen backends + a provider-routing factoryget_driver+ shared FILE:/markdown extraction utilities. -
Verified:
- ✅ FR-001 / FR-012 Protocol.
AsyncCodeDriver(drivers/base.py:20) is@runtime_checkable(:19) withexecute(task, files, is_fix) -> tuple[bool, str](:32). Traces nowspec="025"(the spec's "next pass updates decorators to 025" is done). - ✅ 7 drivers present.
ClaudeCodeDriver(claude_code_driver.py:119),ClaudeAPIDriver(claude_api_driver.py:98),AiderDriver(aider_driver.py:77),DeepSeekCoderDriver(deepseek_coder_driver.py:276),QwenDriver(qwen_driver.py:112),BrowserDriver(browser_driver.py:34),BrowserProviderConfig(browser_providers.py:20). - ✅ FR-002 factory + FR-011 fallback.
get_driver(driver_factory.py:46) readsget_volk_providerfromorchestrata_ultimate.llm.config(:72); routing tableclaude/anthropic→ClaudeAPIDriver,deepseek/openrouter→DeepSeekCoderDriver,aider→AiderDriver,qwen/ollama→QwenDriver,*_browser→BrowserDriver,claude_code→ClaudeCodeDriver, unknown→ClaudeAPIDriverwith warning (:99-105). Wired —refs get_driver→agents/swarm/coordinator.py:417,agents/volks/codedirector/volk.py:502,agents/volks/junior/volk.py:215. - ✅ FR-010 extraction.
extract_file_blocks(extraction.py:21),extract_markdown_code_blocks(:63). - ✅ FR-003/FR-004 CLI + timeout. each CLI driver locates binary via
shutil.whichand wraps subprocess inasyncio.wait_for(e.g.aider_driver._run_process:173,claude_code_driver._run_process:361). - ✅ FR-005 workspace scan.
ClaudeAPIDriverscans post-execution for source files (claude_api_driver.py:135+). - ✅ FR-007/FR-008/FR-009 browser.
BrowserDriversession persistence_save_storage_state(:402), 3-tier recovery_recover_session(:374), rate limit_enforce_rate_limit(:208), expiry_is_session_expired(:196). - ⚠️ FR-006 DeepSeek direct-API — DIVERGENT.
DeepSeekCoderDriver.execute(deepseek_coder_driver.py:299) routes throughcall_llm(CODER_SYSTEM_PROMPT, prompt, temperature=0.2, volk="J:Junior")(:321-325) — no direct DeepSeek HTTP call, nomodel=deepseek-coder, noDEEPSEEK_API_KEY. Class docstring "using DeepSeek API directly" (:277) is stale. Driver is richer than spec (_retry_on_empty,_recover_missing_files,_autofix_lint,_validate_written_files). Fresh detail (2026-10-18):openrouternow ALSO routes toDeepSeekCoderDriver(driver_factory.py:74-85, with an explanatory comment) — prior audit listed onlydeepseek.
- ✅ FR-001 / FR-012 Protocol.
-
Remaining work / plan: (spec-only, no code change)
- Scope: update SPEC-025 FR-006 +
DeepSeekCoderDriversection + ERR-010/011 to state the driver routes viacall_llm(SPEC-028) and is provider-agnostic (also servesopenrouter), not a direct DeepSeek HTTP client. - Target files:
specs/025-code-generation-drivers/spec.md. - Approach: rewrite the two divergent paragraphs; optionally note the extra validation/recovery behavior.
- Dependencies: SPEC-028 (
call_llm) — divergence exists because of the facade consolidation. - Effort: S. Risk: low (documentation reconciliation).
- Scope: update SPEC-025 FR-006 +
-
Evidence log:
symbols AsyncCodeDriver|get_driver|extract_file_blocks|extract_markdown_code_blocks→ all present.symbols ClaudeCodeDriver|ClaudeAPIDriver|AiderDriver|DeepSeekCoderDriver|QwenDriver|BrowserDriver|BrowserProviderConfig→ 7 present.source drivers.base→@runtime_checkableat:19.source drivers.driver_factory→ routing table incl.openrouterbranch:74-85.source drivers.deepseek_coder_driver→call_llm(...volk="J:Junior")at:321-325; no HTTP/DEEPSEEK_API_KEY.refs get_driver→ 3 production consumers.
SPEC-028 LLM Client Facade — DIVERGENCE (core DONE; API redesigned)
-
Specifies: single async
call_llm()entry +call_reasoner(), per-volkVolkConfigwith env overrides,resolve_provider/resolve_model, transient retry, KG injection + compliance validation, lazyProviderManagersingleton,LLMClientError/LLMProviderUnavailableError. -
Verified:
- ✅ FR-001/FR-002 single entry.
call_llm(llm/client.py:819),call_reasoner(:984, delegates tocall_llmwith reasoning tier). Wired —refs call_llm→ 11 production USE sites (viaagents/volks/base.py:243_call_llmwrapper and direct callers). - ✅ FR-005/FR-006 retry.
MAX_RETRIES = 6,RETRY_DELAYS = [5,10,20,40,60,60](:52-53);_is_transient(:519,_TRANSIENT_MARKERSincl. 429/500/502/503/timeout/connection-refused) +_is_rate_limit_error(:539);_execute_with_retry(:570, backoff loop + 900s total budget). Spec default is 5 — numeric tuning for deepseek 429 windows. - ✅ FR-007 KG injection.
graph_contextprepended touser_messageincall_llm(:852-857) with a## Entities usedcompliance prompt appended tosystem_prompt. - ✅ FR-008 compliance validation.
GraphContextValidator(knowledge_graph/graph_context_validator.py:87)MAX_VALIDATION_RETRIESloop (client.py:892-960); returns non-compliant response with error log after retries.
- ✅ FR-004/FR-012/FR-013 adapter registration + lazy singleton.
_register_adapters(:461),_register_*forclaude_cli/anthropic/deepseek/openai/openrouter/ollama(:404-446) — 6 providers (spec lists 5;openaiis an extra);_get_provider_managerlazy singleton with lock (:482). - ✅ FR-010 exceptions.
LLMClientError(llm/exceptions.py:8),LLMProviderUnavailableError(:17, subclass). - ✅ FR-009 env overrides — RESOLVED divergence (trusted; spec updated 2026-07).
llm/config.pydocstring states "single source of truth isspike-profiles.yaml. No env variable overrides"; profile selected bySPIKE_PROFILE;PROVIDER_MODELS(config.py:38-65);REASONING_AGENTS = {"U:Ar","U:SD"}(:33). - ❌ FR-011
resolve_provider()/resolve_model()— ABSENT.symbols resolve_provider→ 0;resolve_modelonly hit isproviders/registry.py:80(unrelated). Replaced byget_volk_provider(llm/config.py:323) /get_volk_model(:342). - ⚠️ Signature/return DIVERGENCE. Spec
call_llm(volk_alias, messages, knowledge_graph_context, provider_override, model_override, reasoning_model_override, max_retries_override, metadata) -> LLMResponse; actualcall_llm(system_prompt, user_message, model, temperature, volk, graph_context, env) -> str(:819). NoLLMResponse/LLMRequestobjects, noprovider_override/model_override/reasoning_model_override/max_retries_override/metadataparams, no per-VolkORCHESTRATA_LLM_MODEL_U:AR. Thestrreturn matches the spec's own US-028-001 ("Return type is a plainstr") — the spec is internally inconsistent. FR-014compliance_verifiedmetadata is therefore not expressible (return is a barestr+ warning log). - ⚠️ Duplicate config (orphaned parallel path).
core/infra_config.pystill honorsORCHESTRATA_LLM_PROVIDER/_MODEL/_REASONING_MODEL(:114/:118/:120) and exposesget_volk_provider(:149)/get_volk_model(:156) with_REASONING_VOLKS = {"U:Ar"}(:101) — inconsistent withllm/config.py'sREASONING_AGENTS={"U:Ar","U:SD"}. The LLM client + driver factory importorchestrata_ultimate.llm.config, notinfra_config, so the env-override path is orphaned for LLM routing.
- ✅ FR-001/FR-002 single entry.
-
Remaining work / plan: (spec update + a duplication cleanup decision — no functional hole)
- Scope: rewrite SPEC-028 to the profiles-based redesign (
SPIKE_PROFILE-selectedspike-profiles.yaml, no env overrides,str-returningcall_llm(system_prompt,user_message,…),get_volk_provider/get_volk_modelin place ofresolve_provider/resolve_model,MAX_RETRIES=6). Separately decide the fate ofcore/infra_config.py's duplicate LLM config (retire or wire as the deliberate CLI/test override layer). - Target files:
specs/028-llm-client/spec.md; decision oncore/infra_config.pyLLM block. No change tollm/client.py/llm/config.py(intended design). - Approach: reconcile the spec text; for the infra_config duplicate, make a consolidation call (touches many env-config sites; relates to the "read env at call time" note).
- Dependencies: SPEC-011 (ProviderManager), SPEC-025 (
driver_factoryimportsllm.config),core/infra_config. - Effort: S (spec) / M (if infra_config consolidation is taken). Risk: low/med.
- Scope: rewrite SPEC-028 to the profiles-based redesign (
-
Evidence log:
symbols call_llm|call_reasoner|resolve_provider|resolve_model→ call_llm:819, call_reasoner:984, resolve_* absent (onlyregistry.py:80).source llm.client(head + retry + call_llm):MAX_RETRIES=6,_TRANSIENT_MARKERS, KG injection:852-857, compliance loop:892-960.source llm.config→ profile-based,PROVIDER_MODELS,REASONING_AGENTS,get_volk_provider:323/get_volk_model:342.source core.infra_config→ORCHESTRATA_LLM_*env overrides:114-125,_REASONING_VOLKS={"U:Ar"}:101,get_volk_provider:149/get_volk_model:156.symbols LLMClientError|LLMProviderUnavailableError→exceptions.py:8/:17.refs call_llm→ 11 production USE.
SPEC-053 OpenRouter Provider — DIVERGENCE (realized as an adapter under SPEC-011/028)
-
Specifies: a standalone
OpenRouterProvider(chat_completion/get_available_models/get_model_cost) owning multi-provider access,FALLBACK_CHAINS,RETRY_CONFIG,MODEL_PRICING/calculate_cost, budget enforcement/alerts, caching, audit — a monolithic provider subsystem. -
Verified:
- ❌ No standalone
OpenRouterProvider.symbols OpenRouterProvider→ 0. Nochat_completion/get_available_models/get_model_cost/call_with_fallback/MaxRetriesExceededError. - ❌ No spec constants.
symbols FALLBACK_CHAINS→ 0;MODEL_PRICING→ 0;RETRY_CONFIG→ 0. The onlycalculate_costis SPEC-011'sCostTracker.calculate_cost(cost_tracker.py:95), not a standalone function. - ✅ OpenRouter realized as an adapter.
OpenRouterAdapter(BaseAdapter)(providers/adapters/openrouter_adapter.py:29) withcomplete(OpenAI-compatiblePOST /chat/completionsatOPENROUTER_BASE_URLhttps://openrouter.ai/api/v1, HTTP-Referer/X-Title headers:37-48, tool-call forwarding:83-99),get_models(:127),supports_capability(:145). Wired —refs OpenRouterAdapter→llm/client.py:267(import) +:312(registered in_register_openrouter); alsoscripts/ask_openrouter.py. - 🔻 Responsibilities decomposed. Fallback chain + circuit breaker + cost tracking + budget → SPEC-011
(
router.py,circuit_breaker.py,cost_tracker.py); retry/backoff → SPEC-028 (_execute_with_retry). FR-002/003/004/005/007 exist system-wide, not OpenRouter-owned. Per-agent routing =spike-profiles.yaml; OpenRouter-specific escalation =OPENROUTER_MODEL_ESCALATIONS(llm/config.py:70-79).PROVIDER_MODELS["openrouter"](config.py:48-51) registers qwen family models. - ❌ FR-011 caching absent. No model-list (1h) / pricing (24h) / routing (1h) cache in
openrouter_adapter.pyorregistry.py. - 🔻 External-integration points out of scope for this codebase. REQ-053-052 REST API
(
GET /api/v1/modelsetc.), REQ-053-071/072 (Postgres/RabbitMQ/Stripe/Kong/ELK) are integration contracts from a pre-port spec with nosrc/realization and no consumer.
- ❌ No standalone
-
Remaining work / plan: (spec reconciliation — no real code work)
- Scope: rewrite/retire SPEC-053 to state "OpenRouter is an
IProvideradapter (OpenRouterAdapter) plugged into the SPEC-011 ProviderManager; routing/fallback/cost/budget/retry are owned by SPEC-011 + SPEC-028." Drop theOpenRouterProviderclass contract,FALLBACK_CHAINS/MODEL_PRICING/RETRY_CONFIGduplication, and the Postgres/RabbitMQ/Stripe/Kong integration points. Optionally implement model-list/pricing caching if the perf target is wanted (that would be S/M code, not spec). - Target files:
specs/053-openrouter-provider/spec.md(mark superseded-by-011+028); optionalopenrouter_adapter.py/registry.pycache. - Approach: reconcile SPEC-011/028/053 in one pass (053 overlaps both).
- Dependencies: SPEC-011 + SPEC-028.
- Effort: S (spec) / S–M (if caching added). Risk: low.
- Scope: rewrite/retire SPEC-053 to state "OpenRouter is an
-
Evidence log:
symbols OpenRouterProvider→ 0;symbols FALLBACK_CHAINS/MODEL_PRICING/RETRY_CONFIG→ 0.symbols OpenRouterAdapter→openrouter_adapter.py:29;refs OpenRouterAdapter→llm/client.py:267/:312.source providers.adapters.openrouter_adapter→ OpenAI-compatible endpoint, headers,get_models,supports_capability.source llm.config→OPENROUTER_MODEL_ESCALATIONS,PROVIDER_MODELS["openrouter"].
Cluster summary table
| Spec | Class | Effort | Hard deps |
|---|---|---|---|
| SPEC-011 Provider Manager | PARTIAL (FR-015 done; FR-013 gov / FR-014 Neo4j audit / EventBus emission absent; FR-005 config divergence) | L | Prolog-janus governance (SPEC-013), kernel EventBus (SPEC-001), Neo4j + session.closed wiring (shared w/ SPEC-010 FR-008) |
| SPEC-025 Code-Gen Drivers | DONE (FR-006 DeepSeek direct-API → routes via call_llm: divergence) |
S (spec) | SPEC-028 call_llm |
| SPEC-028 LLM Client | DIVERGENCE (core done+wired; profiles redesign: no env overrides, no resolve_*, str return) |
S spec / M if infra_config consolidated | SPEC-011, SPEC-025; core/infra_config duplicate-config cleanup |
| SPEC-053 OpenRouter | DIVERGENCE (built as OpenRouterAdapter under SPEC-011/028, not standalone OpenRouterProvider) |
S (spec) / S–M if caching added | SPEC-011 + SPEC-028 (reconcile together) |
Notes / non-gaps (do NOT "fix")
memory/token_counter.py:59except ImportError, KeyError:anddeepseek_coder_driver.py:505except OSError, UnicodeDecodeError:remain valid PEP-758 parenthesis-freeexcepton Python 3.14 — not bugs._execute_with_retrynow carries a cassette layer (LLM_CASSETTE_DIR/LLM_CASSETTE_SYNTH/LLM_CASSETTE_RECORD) and a 900s total retry budget — the 2026-08-05 CXP accept-queue wedge mitigation. Not spec-required; not a gap.
Cross-cluster dependencies noticed
- SPEC-011 ↔ SPEC-010: both need the same unresolved
session.closed→ EventBus/persistent-engine wiring (SPEC-011 Neo4j cost cold-migration; SPEC-010 FR-008 memorymigrate_to_cold). Solve once. - SPEC-011 ↔ governance (SPEC-013 PAM++/janus): FR-013 model-access + budget-override predicates depend on the Prolog-janus adapter.
- SPEC-011 ↔ SPEC-001 EventBus: provider event emission depends on
kernel.emit_event. - SPEC-028 ↔ core/infra_config: a duplicate env-honoring
get_volk_provider/get_volk_modelcoexists with the livellm/config.py; consolidation is a design decision. Touches SPEC-025 (driver_factoryimportsllm.config). - SPEC-053 ⊂ SPEC-011 + SPEC-028: reconcile the three specs in one pass.