[AUTO-GUARD-1] Module Coupling: CLI and Application layers bypass A2A boundary with direct service imports #9962

Open
opened 2026-04-16 08:50:25 +00:00 by HAL9000 · 1 comment
Owner

Metadata

  • Commit message: refactor: route CLI→Application communication through A2A boundary
  • Branch name: refactor/auto-guard-1-cli-a2a-boundary

Background and Context

The architecture specification mandates that the CLI (Presentation layer) communicates with the Application layer exclusively through the A2A protocol boundary. However, the CLI layer directly imports and instantiates Application layer services, bypassing this boundary entirely.

Per the specification (architecture/README.md):

A2A is the fundamental boundary between Presentation and Application layers. It ensures all clients (CLI, TUI, IDE, third-party) are interchangeable.

The intended flow is:

CLI → A2A over stdio → A2aLocalFacade → ServiceFacade.method()

Actual Implementation

The CLI directly imports Application services in 83+ locations:

src/cleveragents/cli/commands/plan.py (most severe — 83 direct service imports):

# Line 487-488
from cleveragents.application.services.plan_service import PlanService
from cleveragents.application.services.project_service import ProjectService

# Line 1694-1699
from cleveragents.application.services.execute_phase_context_assembler import ExecutePhaseContextAssembler
from cleveragents.application.services.llm_actors import LLMExecuteActor
from cleveragents.application.services.plan_executor import PlanExecutor
from cleveragents.application.services.strategy_actor import StrategyActor

src/cleveragents/cli/commands/context.py — imports ContextService and ProjectService in 8+ function bodies

src/cleveragents/cli/commands/resource.py — imports ResourceRegistryService at module level (line 67)

src/cleveragents/cli/commands/skill.py — imports SkillService at module level (line 50)

src/cleveragents/cli/commands/invariant.py — imports InvariantService at module level (line 46)

Additional Layer Violation

src/cleveragents/application/services/plan_apply_service.py (line 344):

from cleveragents.cli.formatting import format_output

This is a reverse dependency — Application layer importing from Presentation layer, which is strictly forbidden by the layered architecture.

CLI importing Infrastructure layer directly:

  • src/cleveragents/cli/commands/plan.py:1362 — imports git_worktree from infrastructure
  • src/cleveragents/cli/commands/plan.py:3861 — imports UnitOfWork from infrastructure
  • src/cleveragents/cli/commands/resource.py:721 — imports database models from infrastructure
  • src/cleveragents/cli/commands/tool.py:88 — imports repositories from infrastructure

Expected Behavior

  • All CLI→Application communication is routed exclusively through A2aLocalFacade
  • No direct imports of Application layer services from CLI layer exist
  • No reverse dependencies (Application importing from Presentation) exist
  • No direct CLI→Infrastructure imports exist (all go through Application layer)
  • Import-linter rules in CI enforce these boundaries automatically

Acceptance Criteria

  • All CLI commands communicate with Application layer only through A2aLocalFacade
  • src/cleveragents/cli/commands/plan.py contains zero direct imports from cleveragents.application.services.*
  • src/cleveragents/cli/commands/context.py contains zero direct imports from cleveragents.application.services.*
  • src/cleveragents/cli/commands/resource.py contains zero direct imports from cleveragents.application.services.*
  • src/cleveragents/cli/commands/skill.py contains zero direct imports from cleveragents.application.services.*
  • src/cleveragents/cli/commands/invariant.py contains zero direct imports from cleveragents.application.services.*
  • src/cleveragents/application/services/plan_apply_service.py contains zero imports from cleveragents.cli.*
  • CLI→Infrastructure direct imports are removed (use Application layer services instead)
  • Import-linter rules added to CI to enforce layer boundaries
  • All existing tests pass after refactoring

Subtasks

  • Audit all CLI command files for direct Application service imports
  • Audit all Application service files for reverse Presentation layer imports
  • Audit all CLI command files for direct Infrastructure layer imports
  • Route plan.py CLI commands through A2aLocalFacade
  • Route context.py CLI commands through A2aLocalFacade
  • Route resource.py CLI commands through A2aLocalFacade
  • Route skill.py CLI commands through A2aLocalFacade
  • Route invariant.py CLI commands through A2aLocalFacade
  • Move format_output from cleveragents.cli.formatting to a shared utility module
  • Remove reverse dependency in plan_apply_service.py
  • Remove CLI→Infrastructure direct imports (git_worktree, UnitOfWork, database models, repositories)
  • Add import-linter rules to enforce CLI→A2A→Application boundary in CI
  • Add import-linter rules to enforce no Application→Presentation reverse dependencies
  • Run full test suite and fix any regressions

Definition of Done

This issue should be closed when:

  1. All CLI commands communicate with Application layer exclusively through A2aLocalFacade
  2. No reverse dependencies (Application→Presentation) exist in the codebase
  3. No direct CLI→Infrastructure imports exist
  4. Import-linter CI rules are in place and passing
  5. All existing tests pass
  6. A code review has approved the changes

References

  • src/cleveragents/cli/commands/plan.py (lines 487, 522, 556, 583, 610, 637, 665, 692, 724, 882, 986, 1066, 1156, 1169, 1201, 1254, 1294, 1694-1699, 2052, 2320, 2556, 3236, 3281, 3761, 4233)
  • src/cleveragents/application/services/plan_apply_service.py:344
  • Architecture spec: docs/architecture.md
  • ADR-001: Layered Architecture

Automated by CleverAgents Bot
Agent: new-issue-creator

## Metadata - **Commit message**: `refactor: route CLI→Application communication through A2A boundary` - **Branch name**: `refactor/auto-guard-1-cli-a2a-boundary` ## Background and Context The architecture specification mandates that the CLI (Presentation layer) communicates with the Application layer exclusively through the A2A protocol boundary. However, the CLI layer directly imports and instantiates Application layer services, bypassing this boundary entirely. Per the specification (`architecture/README.md`): > A2A is the **fundamental boundary between Presentation and Application layers**. It ensures all clients (CLI, TUI, IDE, third-party) are interchangeable. The intended flow is: ``` CLI → A2A over stdio → A2aLocalFacade → ServiceFacade.method() ``` ### Actual Implementation The CLI directly imports Application services in 83+ locations: **`src/cleveragents/cli/commands/plan.py`** (most severe — 83 direct service imports): ```python # Line 487-488 from cleveragents.application.services.plan_service import PlanService from cleveragents.application.services.project_service import ProjectService # Line 1694-1699 from cleveragents.application.services.execute_phase_context_assembler import ExecutePhaseContextAssembler from cleveragents.application.services.llm_actors import LLMExecuteActor from cleveragents.application.services.plan_executor import PlanExecutor from cleveragents.application.services.strategy_actor import StrategyActor ``` **`src/cleveragents/cli/commands/context.py`** — imports `ContextService` and `ProjectService` in 8+ function bodies **`src/cleveragents/cli/commands/resource.py`** — imports `ResourceRegistryService` at module level (line 67) **`src/cleveragents/cli/commands/skill.py`** — imports `SkillService` at module level (line 50) **`src/cleveragents/cli/commands/invariant.py`** — imports `InvariantService` at module level (line 46) ### Additional Layer Violation **`src/cleveragents/application/services/plan_apply_service.py`** (line 344): ```python from cleveragents.cli.formatting import format_output ``` This is a reverse dependency — Application layer importing from Presentation layer, which is strictly forbidden by the layered architecture. ### CLI importing Infrastructure layer directly: - `src/cleveragents/cli/commands/plan.py:1362` — imports `git_worktree` from infrastructure - `src/cleveragents/cli/commands/plan.py:3861` — imports `UnitOfWork` from infrastructure - `src/cleveragents/cli/commands/resource.py:721` — imports database models from infrastructure - `src/cleveragents/cli/commands/tool.py:88` — imports repositories from infrastructure ## Expected Behavior - All CLI→Application communication is routed exclusively through `A2aLocalFacade` - No direct imports of Application layer services from CLI layer exist - No reverse dependencies (Application importing from Presentation) exist - No direct CLI→Infrastructure imports exist (all go through Application layer) - Import-linter rules in CI enforce these boundaries automatically ## Acceptance Criteria - [ ] All CLI commands communicate with Application layer only through `A2aLocalFacade` - [ ] `src/cleveragents/cli/commands/plan.py` contains zero direct imports from `cleveragents.application.services.*` - [ ] `src/cleveragents/cli/commands/context.py` contains zero direct imports from `cleveragents.application.services.*` - [ ] `src/cleveragents/cli/commands/resource.py` contains zero direct imports from `cleveragents.application.services.*` - [ ] `src/cleveragents/cli/commands/skill.py` contains zero direct imports from `cleveragents.application.services.*` - [ ] `src/cleveragents/cli/commands/invariant.py` contains zero direct imports from `cleveragents.application.services.*` - [ ] `src/cleveragents/application/services/plan_apply_service.py` contains zero imports from `cleveragents.cli.*` - [ ] CLI→Infrastructure direct imports are removed (use Application layer services instead) - [ ] Import-linter rules added to CI to enforce layer boundaries - [ ] All existing tests pass after refactoring ## Subtasks - [ ] Audit all CLI command files for direct Application service imports - [ ] Audit all Application service files for reverse Presentation layer imports - [ ] Audit all CLI command files for direct Infrastructure layer imports - [ ] Route `plan.py` CLI commands through `A2aLocalFacade` - [ ] Route `context.py` CLI commands through `A2aLocalFacade` - [ ] Route `resource.py` CLI commands through `A2aLocalFacade` - [ ] Route `skill.py` CLI commands through `A2aLocalFacade` - [ ] Route `invariant.py` CLI commands through `A2aLocalFacade` - [ ] Move `format_output` from `cleveragents.cli.formatting` to a shared utility module - [ ] Remove reverse dependency in `plan_apply_service.py` - [ ] Remove CLI→Infrastructure direct imports (git_worktree, UnitOfWork, database models, repositories) - [ ] Add import-linter rules to enforce CLI→A2A→Application boundary in CI - [ ] Add import-linter rules to enforce no Application→Presentation reverse dependencies - [ ] Run full test suite and fix any regressions ## Definition of Done This issue should be closed when: 1. All CLI commands communicate with Application layer exclusively through `A2aLocalFacade` 2. No reverse dependencies (Application→Presentation) exist in the codebase 3. No direct CLI→Infrastructure imports exist 4. Import-linter CI rules are in place and passing 5. All existing tests pass 6. A code review has approved the changes ## References - `src/cleveragents/cli/commands/plan.py` (lines 487, 522, 556, 583, 610, 637, 665, 692, 724, 882, 986, 1066, 1156, 1169, 1201, 1254, 1294, 1694-1699, 2052, 2320, 2556, 3236, 3281, 3761, 4233) - `src/cleveragents/application/services/plan_apply_service.py:344` - Architecture spec: `docs/architecture.md` - ADR-001: Layered Architecture --- **Automated by CleverAgents Bot** Agent: new-issue-creator
Author
Owner

Triage Decision [AUTO-OWNR]

Status: Verified

Type: Refactor
Priority: High
MoSCoW: Should Have
Milestone: v3.5.0

Rationale: CLI and Application layers bypassing the A2A boundary with direct service imports is an architectural violation that will become increasingly problematic as the A2A facade is implemented in v3.5.0. Refactoring to respect the A2A boundary is Should Have — important for clean architecture but not immediately blocking current functionality.


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

## Triage Decision [AUTO-OWNR] **Status**: ✅ Verified **Type**: Refactor **Priority**: High **MoSCoW**: Should Have **Milestone**: v3.5.0 **Rationale**: CLI and Application layers bypassing the A2A boundary with direct service imports is an architectural violation that will become increasingly problematic as the A2A facade is implemented in v3.5.0. Refactoring to respect the A2A boundary is Should Have — important for clean architecture but not immediately blocking current functionality. --- **Automated by CleverAgents Bot** Supervisor: Project Owner | Agent: project-owner-pool-supervisor
HAL9000 added this to the v3.5.0 milestone 2026-04-16 10:35:22 +00:00
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#9962
No description provided.