You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
From the 2026-05-31 full-codebase review (epic #3143). Domain health: adequate. This issue is the durable, individually-trackable list of findings for this domain; thematic work is tracked under epic #3143 (related phase: #3150).
Evidence: /src/adapters/resilient-adapter.ts:70 (IModelAdapter plane) vs /src/cli-adapters/composite-router.ts:163 (ICliAdapter plane)
Fix: Define a unified adapter interface that supports both model-level (provider) and CLI-level (subprocess) dispatch. Implement adapter composition layer so routing decisions can express model preferences, not just CLI choices. Unifies the two planes into a single routing→model→execute pipeline.
[HIGH][modularity] UnifiedAdapterRegistry not exported; building-block vision unrealized
Evidence: /src/adapters/index.ts:172-180 exports UnifiedAdapterRegistry, but /src/exports/adapters.ts does not; only internal code (cli-server.ts) imports it
Fix: Export UnifiedAdapterRegistry from main entry points (src/index.ts, src/exports/adapters.ts). Add public factory function createUnifiedRegistry(). Document as a reusable primitive for custom routing logic. Enables operators to build domain-specific routing strategies without reaching into internals.
Evidence: /src/adapters/unified-registry.ts:299-311 (buildTaskRouting called once in constructor); /src/config/model-registry.ts:292-314 (lazy singleton built once, never refreshed)
Fix: Implement hot-reload for model registry: either subscription-based (routing subscribes to registry change events) or polling-based (periodic re-check of task specialization matrix). Ensure manifest overlays applied post-startup (e.g., via NEXUS_MODELS_OVERLAY_PATH update) propagate to routing decisions within bounded time.
Evidence: /src/adapters/resilient-adapter.ts:162-167 (clears currentAdapter synchronously without quiescing inflight); line 196-200 (dispose does not block or drain pending work)
Fix: Implement quiescence tracking: before clearing cached adapter, wait for ongoing requests to drain (with timeout). Add onFailover callback guarantee—either all callbacks complete or log which failed. Consider async dispose() signature instead of void. Prevents mid-request adapter swap from corrupting streaming state.
Evidence: /src/adapters/model-not-found-fallback.ts:135-150 (completeWithFallback detects 404, picks fallback, retries, surfaces second error with no retirement indicator); onRetirement callback defined but never wired in production code
Fix: Wire onRetirement callback through adapter construction path. Log retirement decision with modelId, fallback id, and reason (e.g., vendor 404). Emit event to orchestration observer for telemetry/alerting. Helps operators detect vendor model churn and adjust task specialization matrix before outages.
Evidence: /src/cli-adapters/composite-router.ts:639-653 (getCandidateCliNames silently falls back to all CLIs if cache is undefined or returns empty)
Fix: Make cache wiring explicit: warn at router construction time if cache is undefined but would be useful (e.g., in multi-tenant mode). Log cache misses / fallback-to-all events at INFO level. Optionally fail routing if cache is configured but returns empty (strict mode for operators who depend on it).
Evidence: /src/cli-adapters/composite-router.ts:601-607 (route picks CLI, builds CliTask); /src/cli-adapters/types-capability.ts:70-85 (CliTask.model is optional); subprocess adapter then selects default model or task.model override
Fix: Elevate model selection to routing tier: add required model field to CliTask, compute it in routing pipeline (not deferred to subprocess). Route returns (CLI, Model) pair explicitly. Allows routing stages to see full decision and enables per-model quality scores, cost estimates, and capability matching.
Evidence: /src/adapters/factory.ts:79-195 (extensible factory with registry) vs /src/cli-adapters/factory.ts:51-75 (createCliAdapter is switch statement, not composable)
Fix: Implement factory registry for CLI adapters: registerCliAdapterCreator(cli, creator). Swap hardcoded switch for factory.get(). Enables operators to plug in custom CLI implementations (e.g., OpenCode variant, internal tool bridge) without modifying core code.
Composability notes
The domain is currently adequate for the CLI orchestrator use case (cli/orchestrate-command.ts) but NOT composable as building blocks. UnifiedAdapterRegistry, model registry, and adapter factories are internal primitives. External pipelines cannot import registry to implement custom routing, observe model fallback/retirement events, hot-reload model metadata post-startup, or implement custom adapters via factory pattern. To enable building-blocks→pipelines vision: export UnifiedAdapterRegistry and factories as public API, implement subscription-based model registry updates, define adapter lifecycle event contracts, and replace hardcoded CLI switch with extensible factory."
Mission gaps
Routing decisions express CLI choice only, not model preference; decouples model selection from task requirements
UnifiedAdapterRegistry is not publicly composable; operators cannot implement domain-specific routing strategies
Model metadata changes post-startup (manifest overlays) do not propagate to cached routing decisions
Adapter lifecycle events (failover, retirement, disposal) are not observable to external systems for telemetry and orchestration
CLI adapters hardcoded in switch statement; no plugin/extensibility path for custom CLI implementations
Part of epic #3143. Full review record: docs/archive/system-review-2026-05-31.md.
Findings catalog — routing-adapters-models
From the 2026-05-31 full-codebase review (epic #3143). Domain health:
adequate. This issue is the durable, individually-trackable list of findings for this domain; thematic work is tracked under epic #3143 (related phase: #3150).Findings
/src/adapters/resilient-adapter.ts:70 (IModelAdapter plane) vs /src/cli-adapters/composite-router.ts:163 (ICliAdapter plane)/src/adapters/index.ts:172-180 exports UnifiedAdapterRegistry, but /src/exports/adapters.ts does not; only internal code (cli-server.ts) imports it/src/adapters/unified-registry.ts:299-311 (buildTaskRouting called once in constructor); /src/config/model-registry.ts:292-314 (lazy singleton built once, never refreshed)/src/adapters/resilient-adapter.ts:162-167 (clears currentAdapter synchronously without quiescing inflight); line 196-200 (dispose does not block or drain pending work)/src/adapters/model-not-found-fallback.ts:135-150 (completeWithFallback detects 404, picks fallback, retries, surfaces second error with no retirement indicator); onRetirement callback defined but never wired in production code/src/cli-adapters/composite-router.ts:639-653 (getCandidateCliNames silently falls back to all CLIs if cache is undefined or returns empty)/src/cli-adapters/composite-router.ts:601-607 (route picks CLI, builds CliTask); /src/cli-adapters/types-capability.ts:70-85 (CliTask.model is optional); subprocess adapter then selects default model or task.model override/src/adapters/factory.ts:79-195 (extensible factory with registry) vs /src/cli-adapters/factory.ts:51-75 (createCliAdapter is switch statement, not composable)Composability notes
The domain is currently adequate for the CLI orchestrator use case (cli/orchestrate-command.ts) but NOT composable as building blocks. UnifiedAdapterRegistry, model registry, and adapter factories are internal primitives. External pipelines cannot import registry to implement custom routing, observe model fallback/retirement events, hot-reload model metadata post-startup, or implement custom adapters via factory pattern. To enable building-blocks→pipelines vision: export UnifiedAdapterRegistry and factories as public API, implement subscription-based model registry updates, define adapter lifecycle event contracts, and replace hardcoded CLI switch with extensible factory."
Mission gaps
Part of epic #3143. Full review record:
docs/archive/system-review-2026-05-31.md.