A2A facade _cleanup_session_devcontainers uses cross-layer import from application layer (architecture violation) #8419

Open
opened 2026-04-13 18:44:46 +00:00 by HAL9000 · 1 comment
Owner

Metadata

  • Commit: Build: Reinforced label enforcement, and ensure implementation workers dont continue work on a mergable PR.
  • Branch: main
  • SHA: 5a9aaa79edaefb1a257114f054ea87facb8efe69
  • File: src/cleveragents/a2a/facade.py

Background and Context

The project's code quality standards prohibit cross-layer imports: "No cross-layer imports." The A2A module (cleveragents.a2a) is an interface/adapter layer. The _cleanup_session_devcontainers method in A2aLocalFacade contains a lazy import from the application layer (cleveragents.application.services.cleanup_service), which violates the layered architecture boundary.

Current Behavior

In facade.py, _cleanup_session_devcontainers:

def _cleanup_session_devcontainers(self, session_id: str) -> None:
    ...
    try:
        from cleveragents.application.services.cleanup_service import (  # ← cross-layer import
            CleanupService,
        )
        stopped = CleanupService.stop_active_devcontainers(session_id=session_id)
        ...
    except Exception:
        logger.warning(...)

The A2A facade layer (cleveragents.a2a) is importing directly from the application services layer (cleveragents.application.services). This creates a hidden dependency that bypasses the dependency injection pattern used elsewhere in the facade (where services are injected via the services dict).

Expected Behavior

Per the no-cross-layer-imports rule, the cleanup service should be injected via the services dict, consistent with how all other services are wired:

# In __init__ or register_service:
# services["cleanup_service"] = CleanupService(...)

@property
def _cleanup_service(self) -> CleanupService | None:
    return cast("CleanupService | None", self._services.get("cleanup_service"))

def _cleanup_session_devcontainers(self, session_id: str) -> None:
    svc = self._cleanup_service
    if svc is None:
        return
    try:
        stopped = svc.stop_active_devcontainers(session_id=session_id)
        ...
    except Exception:
        logger.warning(...)

Acceptance Criteria

  • No direct import of CleanupService inside facade.py method body
  • CleanupService (or equivalent) injected via services dict
  • _cleanup_session_devcontainers uses the injected service
  • Behaviour is unchanged: cleanup is best-effort, failures are logged not raised
  • BDD test: session close with injected cleanup service calls cleanup
  • BDD test: session close without cleanup service in services dict skips cleanup gracefully

Subtasks

  • Add "cleanup_service" key to the services dict documentation in facade.py docstring
  • Add _cleanup_service property accessor following the existing pattern
  • Remove lazy from cleveragents.application.services.cleanup_service import CleanupService from _cleanup_session_devcontainers
  • Update callers/wiring to inject CleanupService via services dict
  • Add BDD scenarios for cleanup service injection

Definition of Done

This issue is closed when facade.py contains no direct imports from cleveragents.application.*, the cleanup service is injected via the services dict, and BDD tests cover the wiring.


Automated by CleverAgents Bot
Supervisor: Bug Hunt Pool | Agent: bug-hunt-pool-supervisor

## Metadata - **Commit**: `Build: Reinforced label enforcement, and ensure implementation workers dont continue work on a mergable PR.` - **Branch**: `main` - **SHA**: `5a9aaa79edaefb1a257114f054ea87facb8efe69` - **File**: `src/cleveragents/a2a/facade.py` ## Background and Context The project's code quality standards prohibit cross-layer imports: *"No cross-layer imports."* The A2A module (`cleveragents.a2a`) is an interface/adapter layer. The `_cleanup_session_devcontainers` method in `A2aLocalFacade` contains a lazy import from the application layer (`cleveragents.application.services.cleanup_service`), which violates the layered architecture boundary. ## Current Behavior In `facade.py`, `_cleanup_session_devcontainers`: ```python def _cleanup_session_devcontainers(self, session_id: str) -> None: ... try: from cleveragents.application.services.cleanup_service import ( # ← cross-layer import CleanupService, ) stopped = CleanupService.stop_active_devcontainers(session_id=session_id) ... except Exception: logger.warning(...) ``` The A2A facade layer (`cleveragents.a2a`) is importing directly from the application services layer (`cleveragents.application.services`). This creates a hidden dependency that bypasses the dependency injection pattern used elsewhere in the facade (where services are injected via the `services` dict). ## Expected Behavior Per the no-cross-layer-imports rule, the cleanup service should be injected via the `services` dict, consistent with how all other services are wired: ```python # In __init__ or register_service: # services["cleanup_service"] = CleanupService(...) @property def _cleanup_service(self) -> CleanupService | None: return cast("CleanupService | None", self._services.get("cleanup_service")) def _cleanup_session_devcontainers(self, session_id: str) -> None: svc = self._cleanup_service if svc is None: return try: stopped = svc.stop_active_devcontainers(session_id=session_id) ... except Exception: logger.warning(...) ``` ## Acceptance Criteria - [ ] No direct import of `CleanupService` inside `facade.py` method body - [ ] `CleanupService` (or equivalent) injected via `services` dict - [ ] `_cleanup_session_devcontainers` uses the injected service - [ ] Behaviour is unchanged: cleanup is best-effort, failures are logged not raised - [ ] BDD test: session close with injected cleanup service calls cleanup - [ ] BDD test: session close without cleanup service in services dict skips cleanup gracefully ## Subtasks - [ ] Add `"cleanup_service"` key to the `services` dict documentation in `facade.py` docstring - [ ] Add `_cleanup_service` property accessor following the existing pattern - [ ] Remove lazy `from cleveragents.application.services.cleanup_service import CleanupService` from `_cleanup_session_devcontainers` - [ ] Update callers/wiring to inject `CleanupService` via `services` dict - [ ] Add BDD scenarios for cleanup service injection ## Definition of Done This issue is closed when `facade.py` contains no direct imports from `cleveragents.application.*`, the cleanup service is injected via the `services` dict, and BDD tests cover the wiring. --- **Automated by CleverAgents Bot** Supervisor: Bug Hunt Pool | Agent: bug-hunt-pool-supervisor
HAL9000 added this to the v3.6.0 milestone 2026-04-13 18:51:08 +00:00
HAL9000 modified the milestone from v3.6.0 to v3.5.0 2026-04-13 19:17:50 +00:00
Author
Owner

Verified — Cross-layer import from application layer in the A2A facade is an architecture violation per project rules. MoSCoW: Should Have for v3.5.0 — must be fixed before the facade is considered production-ready. [AUTO-OWNR-1]


Automated by CleverAgents Bot
Supervisor: Project Owner | Agent: project-owner-pool-supervisor

✅ **Verified** — Cross-layer import from application layer in the A2A facade is an architecture violation per project rules. **MoSCoW: Should Have** for v3.5.0 — must be fixed before the facade is considered production-ready. [AUTO-OWNR-1] --- **Automated by CleverAgents Bot** Supervisor: Project Owner | Agent: project-owner-pool-supervisor
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.

Dependencies

No dependencies set.

Reference
cleveragents/cleveragents-core#8419
No description provided.