UAT: Multiple application services missing from DI container - not resolvable via dependency injection #3917

Open
opened 2026-04-06 07:23:26 +00:00 by freemo · 0 comments
Owner

Metadata

  • Branch: fix/register-missing-services-in-di-container
  • Commit Message: fix(container): register missing application services in DI container
  • Milestone: None (backlog — see note below)
  • Parent Epic: #397

Background and Context

Per the specification and CONTRIBUTING.md, the Service Layer Pattern and Dependency Injection are required architectural patterns. All application services must be registered in the DI container (Container class in container.py) so they can be resolved with their dependencies automatically wired. Code-level analysis of src/cleveragents/application/container.py against the full list of services in src/cleveragents/application/services/ reveals that 10 services exist but are not registered in the container.

Current Behavior

The following services exist in src/cleveragents/application/services/ but are NOT registered in the Container class in container.py:

Service Class File Notes
PlanApplyService plan_apply_service.py Requires PlanLifecycleService injection
SubplanExecutionService subplan_execution_service.py Requires SubplanMergeService, executor_fn
PlanResumeService plan_resume_service.py Requires PlanLifecycleService
ErrorRecoveryService error_recovery_service.py Requires PlanLifecycleService
CrossPlanCorrectionService cross_plan_correction_service.py Requires DecisionService
PermissionService permission_service.py Uses module-level singleton workaround
LockService lock_service.py Requires DB session factory
MemoryService memory_service.py Created ad-hoc in PlanService
SkillRegistryService skill_registry_service.py Requires DB session factory
SemanticValidationService semantic_validation_service.py Requires ValidationPipeline

Steps to Reproduce (Code Analysis)

  1. Open src/cleveragents/application/container.py
  2. Search for PlanApplyService, SubplanExecutionService, PlanResumeService, ErrorRecoveryService, CrossPlanCorrectionService, PermissionService, LockService, MemoryService, SkillRegistryService, SemanticValidationService
  3. Observe that none of these classes appear as providers in the Container class

Code Locations

  • Container: src/cleveragents/application/container.py
  • Missing services: src/cleveragents/application/services/plan_apply_service.py, subplan_execution_service.py, plan_resume_service.py, error_recovery_service.py, cross_plan_correction_service.py, permission_service.py, lock_service.py, memory_service.py, skill_registry_service.py, semantic_validation_service.py

Expected Behavior

All application services in src/cleveragents/application/services/ are registered in the Container class with proper dependency wiring, enabling callers to resolve them via container.service_name() with all dependencies automatically injected.

Subtasks

  • Write failing behave unit tests verifying each missing service can be resolved from the container (TDD — tests first)
  • Register PlanApplyService as providers.Factory with lifecycle_service=plan_lifecycle_service
  • Register SubplanExecutionService as providers.Factory with SubplanMergeService and executor_fn wired
  • Register PlanResumeService as providers.Factory with lifecycle_service=plan_lifecycle_service
  • Register ErrorRecoveryService as providers.Factory with lifecycle_service=plan_lifecycle_service
  • Register CrossPlanCorrectionService as providers.Factory with decision_service wired
  • Register PermissionService as providers.Singleton (replacing module-level singleton workaround)
  • Register LockService as providers.Factory with DB session factory wired
  • Register MemoryService as providers.Factory (replacing ad-hoc creation in PlanService._get_memory_service())
  • Register SkillRegistryService as providers.Factory with DB session factory wired
  • Register SemanticValidationService as providers.Factory with ValidationPipeline wired
  • Remove module-level singleton workaround from permission_service.py
  • Remove ad-hoc _get_memory_service() from PlanService and replace with container injection
  • Verify nox -e typecheck passes (pyright)
  • Verify nox -e unit_tests passes with coverage >= 97%
  • Update PR description and link to this issue

Definition of Done

  • All 10 missing services are registered in the Container class with correct dependency wiring
  • PermissionService module-level singleton workaround is removed
  • PlanService._get_memory_service() ad-hoc creation is removed and replaced with container injection
  • behave unit tests verify each service resolves correctly from the container
  • No callers manually instantiate these services outside of the container
  • All nox stages pass
  • Coverage >= 97%

Bug Report

Feature Area: Dependency Injection and Service Layer

Severity: Medium — services exist but cannot be resolved via the DI container, forcing callers to instantiate them manually

Impact

  1. No DI wiring: Callers must manually instantiate these services and wire their dependencies, defeating the purpose of the DI container.
  2. Inconsistent patterns: Some services use module-level singletons (PermissionService) or ad-hoc creation (MemoryService in PlanService._get_memory_service()), bypassing the container entirely.
  3. Testability: Without container registration, overriding these services in tests requires patching at the module level rather than using container.override_providers().
  4. Spec violation: The spec requires the Service Layer Pattern with DI for all application services.

Register each missing service as a providers.Factory or providers.Singleton in the Container class with appropriate dependency wiring. For example:

# In Container class:
plan_apply_service = providers.Factory(
    PlanApplyService,
    lifecycle_service=plan_lifecycle_service,
)

lock_service = providers.Factory(
    _build_lock_service,
    database_url=database_url,
)

Backlog note: This issue was discovered during autonomous operation
on milestone v3.5.0. It does not block milestone completion and has been
placed in the backlog for human review and future milestone assignment.


Automated by CleverAgents Bot
Supervisor: UAT Testing | Agent: ca-new-issue-creator

## Metadata - **Branch**: `fix/register-missing-services-in-di-container` - **Commit Message**: `fix(container): register missing application services in DI container` - **Milestone**: None (backlog — see note below) - **Parent Epic**: #397 ## Background and Context Per the specification and CONTRIBUTING.md, the **Service Layer Pattern** and **Dependency Injection** are required architectural patterns. All application services must be registered in the DI container (`Container` class in `container.py`) so they can be resolved with their dependencies automatically wired. Code-level analysis of `src/cleveragents/application/container.py` against the full list of services in `src/cleveragents/application/services/` reveals that 10 services exist but are not registered in the container. ## Current Behavior The following services exist in `src/cleveragents/application/services/` but are **NOT registered** in the `Container` class in `container.py`: | Service Class | File | Notes | |---|---|---| | `PlanApplyService` | `plan_apply_service.py` | Requires `PlanLifecycleService` injection | | `SubplanExecutionService` | `subplan_execution_service.py` | Requires `SubplanMergeService`, executor_fn | | `PlanResumeService` | `plan_resume_service.py` | Requires `PlanLifecycleService` | | `ErrorRecoveryService` | `error_recovery_service.py` | Requires `PlanLifecycleService` | | `CrossPlanCorrectionService` | `cross_plan_correction_service.py` | Requires `DecisionService` | | `PermissionService` | `permission_service.py` | Uses module-level singleton workaround | | `LockService` | `lock_service.py` | Requires DB session factory | | `MemoryService` | `memory_service.py` | Created ad-hoc in `PlanService` | | `SkillRegistryService` | `skill_registry_service.py` | Requires DB session factory | | `SemanticValidationService` | `semantic_validation_service.py` | Requires `ValidationPipeline` | ### Steps to Reproduce (Code Analysis) 1. Open `src/cleveragents/application/container.py` 2. Search for `PlanApplyService`, `SubplanExecutionService`, `PlanResumeService`, `ErrorRecoveryService`, `CrossPlanCorrectionService`, `PermissionService`, `LockService`, `MemoryService`, `SkillRegistryService`, `SemanticValidationService` 3. Observe that none of these classes appear as providers in the `Container` class ### Code Locations - Container: `src/cleveragents/application/container.py` - Missing services: `src/cleveragents/application/services/plan_apply_service.py`, `subplan_execution_service.py`, `plan_resume_service.py`, `error_recovery_service.py`, `cross_plan_correction_service.py`, `permission_service.py`, `lock_service.py`, `memory_service.py`, `skill_registry_service.py`, `semantic_validation_service.py` ## Expected Behavior All application services in `src/cleveragents/application/services/` are registered in the `Container` class with proper dependency wiring, enabling callers to resolve them via `container.service_name()` with all dependencies automatically injected. ## Subtasks - [ ] Write failing `behave` unit tests verifying each missing service can be resolved from the container (TDD — tests first) - [ ] Register `PlanApplyService` as `providers.Factory` with `lifecycle_service=plan_lifecycle_service` - [ ] Register `SubplanExecutionService` as `providers.Factory` with `SubplanMergeService` and `executor_fn` wired - [ ] Register `PlanResumeService` as `providers.Factory` with `lifecycle_service=plan_lifecycle_service` - [ ] Register `ErrorRecoveryService` as `providers.Factory` with `lifecycle_service=plan_lifecycle_service` - [ ] Register `CrossPlanCorrectionService` as `providers.Factory` with `decision_service` wired - [ ] Register `PermissionService` as `providers.Singleton` (replacing module-level singleton workaround) - [ ] Register `LockService` as `providers.Factory` with DB session factory wired - [ ] Register `MemoryService` as `providers.Factory` (replacing ad-hoc creation in `PlanService._get_memory_service()`) - [ ] Register `SkillRegistryService` as `providers.Factory` with DB session factory wired - [ ] Register `SemanticValidationService` as `providers.Factory` with `ValidationPipeline` wired - [ ] Remove module-level singleton workaround from `permission_service.py` - [ ] Remove ad-hoc `_get_memory_service()` from `PlanService` and replace with container injection - [ ] Verify `nox -e typecheck` passes (pyright) - [ ] Verify `nox -e unit_tests` passes with coverage >= 97% - [ ] Update PR description and link to this issue ## Definition of Done - [ ] All 10 missing services are registered in the `Container` class with correct dependency wiring - [ ] `PermissionService` module-level singleton workaround is removed - [ ] `PlanService._get_memory_service()` ad-hoc creation is removed and replaced with container injection - [ ] `behave` unit tests verify each service resolves correctly from the container - [ ] No callers manually instantiate these services outside of the container - [ ] All nox stages pass - [ ] Coverage >= 97% --- ## Bug Report **Feature Area:** Dependency Injection and Service Layer **Severity:** Medium — services exist but cannot be resolved via the DI container, forcing callers to instantiate them manually ### Impact 1. **No DI wiring**: Callers must manually instantiate these services and wire their dependencies, defeating the purpose of the DI container. 2. **Inconsistent patterns**: Some services use module-level singletons (`PermissionService`) or ad-hoc creation (`MemoryService` in `PlanService._get_memory_service()`), bypassing the container entirely. 3. **Testability**: Without container registration, overriding these services in tests requires patching at the module level rather than using `container.override_providers()`. 4. **Spec violation**: The spec requires the Service Layer Pattern with DI for all application services. ### Recommended Fix Register each missing service as a `providers.Factory` or `providers.Singleton` in the `Container` class with appropriate dependency wiring. For example: ```python # In Container class: plan_apply_service = providers.Factory( PlanApplyService, lifecycle_service=plan_lifecycle_service, ) lock_service = providers.Factory( _build_lock_service, database_url=database_url, ) ``` > **Backlog note:** This issue was discovered during autonomous operation > on milestone v3.5.0. It does not block milestone completion and has been > placed in the backlog for human review and future milestone assignment. --- **Automated by CleverAgents Bot** Supervisor: UAT Testing | Agent: ca-new-issue-creator
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Blocks
#397 Epic: Server & Autonomy Infrastructure
cleveragents/cleveragents-core
Reference
cleveragents/cleveragents-core#3917
No description provided.