docs(spec): add ADR-049 and layer boundary enforcement specification [AUTO-ARCH-24] #10052

Closed
HAL9000 wants to merge 1 commits from spec/auto-arch-24-a2a-boundary-enforcement-adr into master
4 changed files with 112 additions and 0 deletions
+10
View File
@@ -273,6 +273,16 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
a `sqlite3.IntegrityError: UNIQUE constraint failed` crash when `agents plan use` was
called on an action that already had arguments registered via `action create`. (#4197)
### Documentation
- **ADR-049 and Layer Boundary Enforcement Specification** (AUTO-ARCH-24 / #9962): Added
ADR-049 formalizing strict A2A boundary enforcement between Presentation and Application layers.
Documents the A2A protocol as the sole communication channel, forbidden import patterns,
import-linter CI enforcement requirements, and shared utilities placement policy.
Added a corresponding Layer Boundary Enforcement section to `docs/specification.md` documenting
architecture boundaries, prohibited cross-layer imports, permitted communication flow,
and referencing the ADR for detailed rules.
---
## [3.8.0] — 2026-04-05
+1
View File
@@ -21,3 +21,4 @@ Below are some of the specific details of various contributions.
* HAL 9000 has contributed the plugin entry point security hardening fix (#7476): enforced entry point allowlist validation before importing plugin modules to prevent malicious plugin loading.
* This project was made possible thanks to considerable donation of time, money, and resources by CleverThis, Inc.
* HAL 9000 has contributed automated bug fixes, CLI output formatting improvements, and ongoing maintenance as part of the CleverAgents automation system.
* HAL 9000 has contributed the ADR-049 layered architecture boundary enforcement specification (AUTO-ARCH-24 / #9962): formalises strict A2A boundary enforcement between Presentation and Application layers, forbidden import patterns, import-linter CI requirements, and shared utilities policy across `docs/adr/ADR-049-a2a-boundary-enforcement.md` and `docs/specification.md`.
@@ -0,0 +1,59 @@
# ADR-049: Strict A2A Boundary Enforcement Between Presentation and Application Layers
**Date**: 2026-04-16
**Status**: Accepted
**Deciders**: Architecture Team
## Context
The CleverAgents system uses a four-layer architecture (Presentation to Application to Domain to Infrastructure). The A2A protocol is designated as the sole communication channel between the Presentation layer (CLI, TUI, IDE plugins) and the Application layer.
However, the current implementation has accumulated 83+ direct imports from the CLI layer into Application layer services, bypassing the A2A boundary entirely. Additionally, a reverse dependency exists where `plan_apply_service.py` (Application) imports from `cleveragents.cli.formatting` (Presentation).
This ADR formalizes the enforcement of the A2A boundary and establishes import-linter rules to prevent future violations.
## Decision
1. **A2A is the SOLE communication channel** between Presentation and Application layers. No direct imports from `cleveragents.cli.*` into `cleveragents.application.*` are permitted, and vice versa.
2. **Forbidden import patterns**:
- `cleveragents.cli.*` to `cleveragents.application.*` (CLI must not import Application services directly)
- `cleveragents.application.*` to `cleveragents.cli.*` (Application must not import Presentation layer)
- `cleveragents.cli.*` to `cleveragents.infrastructure.*` (CLI must not import Infrastructure directly)
- `cleveragents.presentation.*` to `cleveragents.domain.*` (Presentation must not bypass Application to reach Domain)
3. **Permitted communication flow**:
```
CLI -> A2aLocalFacade (stdio) -> A2aApplicationFacade -> Application Services -> Domain -> Infrastructure
```
4. **Import-linter enforcement**: CI must include import-linter rules that fail the build if any forbidden cross-layer imports are detected.
5. **Shared utilities**: Code needed by both Presentation and Application layers (e.g., formatting utilities) must be placed in `cleveragents.shared.*` or `cleveragents.common.*` -- never in either layer's namespace.
## Consequences
### Positive
- All clients (CLI, TUI, IDE, third-party) become interchangeable -- they all speak A2A
- Layer boundaries are machine-enforced, not just convention
- Enables server-mode deployment where CLI is replaced by HTTP A2A transport
- Eliminates the 83+ direct coupling points that make refactoring difficult
### Negative
- Significant refactoring effort required to migrate existing CLI commands
- A2A method coverage must be expanded to support all operations currently done via direct service calls
- Performance overhead of A2A serialization/deserialization for local calls (mitigated by stdio transport)
### Neutral
- `A2aLocalFacade` becomes the single integration point for all CLI commands
- All new CLI commands must be written against `A2aLocalFacade` from day one
## Implementation Notes
- The refactoring is tracked in issue #9962
- `A2aLocalFacade` must expose methods for all operations currently accessed via direct service imports
- Import-linter configuration goes in `pyproject.toml` under `[tool.importlinter]`
- The `format_output` utility in `cleveragents.cli.formatting` must be moved to `cleveragents.shared.formatting`
+42
View File
3
@@ -43850,6 +43850,48 @@ sequenceDiagram
C-->>U: OK Applied
```
### Layer Boundary Enforcement
!!! adr "Architecture Decision"
The strict A2A boundary enforcement rules and import-linter requirements are defined in [ADR-049: Strict A2A Boundary Enforcement](adr/ADR-049-a2a-boundary-enforcement.md).
#### A2A as the Sole Presentation-to-Application Channel
The A2A protocol is the **only** permitted communication channel between the Presentation layer and the Application layer. This is not merely a convention -- it is a hard architectural rule enforced by CI tooling.
**Forbidden import patterns:**
| From | To | Status |
|------|----|--------|
| `cleveragents.cli.*` | `cleveragents.application.*` | FORBIDDEN |
| `cleveragents.cli.*` | `cleveragents.domain.*` | FORBIDDEN |
| `cleveragents.cli.*` | `cleveragents.infrastructure.*` | FORBIDDEN |
| `cleveragents.application.*` | `cleveragents.cli.*` | FORBIDDEN (reverse dep) |
| `cleveragents.tui.*` | `cleveragents.application.*` | FORBIDDEN |
| `cleveragents.domain.*` | `cleveragents.application.*` | FORBIDDEN (upward dep) |
| `cleveragents.domain.*` | `cleveragents.infrastructure.*` | FORBIDDEN (upward dep) |
**Permitted communication flow:**
Presentation (CLI/TUI/IDE)
-> A2aLocalFacade [stdio transport]
-> A2aApplicationFacade
-> Application Services
-> Domain Entities
-> Infrastructure (via abstract ports)
#### Import-Linter Enforcement
All layer boundary rules are enforced by `import-linter` in CI. The configuration is in `pyproject.toml` under `[tool.importlinter]`. Any PR that introduces a forbidden cross-layer import will fail CI.
#### Shared Utilities
Code needed by multiple layers (e.g., output formatting, common data types) must be placed in `cleveragents.shared.*`. Neither `cleveragents.cli.*` nor `cleveragents.application.*` may contain utilities intended for cross-layer use.
#### ADR Reference
See [ADR-049](adr/ADR-049-a2a-boundary-enforcement.md) for the full decision record.
### Technical Stack
!!! adr "Architecture Decision"