UAT: ADR-001 Violation — Application layer services directly import SQLAlchemy, bypassing the repository pattern #4060

Closed
opened 2026-04-06 09:45:07 +00:00 by freemo · 2 comments
Owner

Metadata

  • Branch: fix/adr-001-sqlalchemy-in-application-layer
  • Commit Message: fix(architecture): remove SQLAlchemy imports from application layer services
  • Milestone: (none — see backlog note below)
  • Parent Epic: (orphan — needs manual linking, see comment)

Bug Report

What was tested: ADR-001 (Layered Architecture) compliance in the Application layer — specifically whether application services access the database through repository interfaces (ports) or directly through SQLAlchemy

Expected behavior (from ADR-001 and ADR-003):
ADR-001 states:

"The Domain Layer must have zero dependencies on infrastructure libraries (no SQLAlchemy imports, no LangChain imports, no HTTP client imports)."
"All service dependencies are wired through the DI container — no direct instantiation of infrastructure components in application or domain code."

The Application layer should access data exclusively through repository interfaces (Protocol classes) defined in the Domain layer, with concrete SQLAlchemy implementations injected via the DI container.

Actual behavior:
Several Application layer services directly import SQLAlchemy, bypassing the repository pattern:

src/cleveragents/application/services/audit_service.py:50-51:
    from sqlalchemy import create_engine
    from sqlalchemy.orm import Session, sessionmaker

src/cleveragents/application/services/phase_gating.py:14:
    from sqlalchemy.exc import OperationalError

src/cleveragents/application/services/repo_indexing_persistence.py:28:
    from sqlalchemy.orm import Session

src/cleveragents/application/services/lock_service.py:32-33:
    from sqlalchemy import delete, func, select
    from sqlalchemy.orm import Session

Specific violations:

  1. audit_service.py creates its own SQLAlchemy engine and session factory directly — it should receive a repository via DI injection
  2. lock_service.py imports and uses SQLAlchemy query primitives (delete, func, select) directly — this is infrastructure-level database access in the application layer
  3. phase_gating.py imports OperationalError from SQLAlchemy — error handling for database-specific exceptions should be in the infrastructure layer
  4. repo_indexing_persistence.py imports Session directly — should use a repository interface

Steps to reproduce:

grep -r "from sqlalchemy" src/cleveragents/application/services/ --include="*.py"

Impact:

  • Application layer is coupled to SQLAlchemy — swapping to a different ORM or database requires changes in the application layer
  • These services cannot be unit-tested without a real database (or complex SQLAlchemy mocking)
  • The hexagonal architecture's testability guarantee is broken for these services
  • ADR-003's DI container pattern is bypassed — these services create their own database connections

Fix:

  1. audit_service.py: Define an AuditRepository Protocol in the domain layer; inject it via DI container; move SQLAlchemy implementation to infrastructure
  2. lock_service.py: Define a LockRepository Protocol; inject via DI; move SQLAlchemy queries to infrastructure
  3. phase_gating.py: Catch generic exceptions in the application layer; let the repository implementation handle SQLAlchemy-specific errors and translate them to domain exceptions
  4. repo_indexing_persistence.py: Inject a repository interface rather than a raw Session

Subtasks

  • Define AuditRepository Protocol in domain layer
  • Move audit_service.py SQLAlchemy code to infrastructure repository implementation
  • Define LockRepository Protocol in domain layer
  • Move lock_service.py SQLAlchemy code to infrastructure repository implementation
  • Update phase_gating.py to catch domain exceptions instead of SQLAlchemy exceptions
  • Update repo_indexing_persistence.py to use repository interface
  • Register new repositories in DI container
  • Update unit tests to use mock repository implementations

Definition of Done

  • Zero from sqlalchemy imports in src/cleveragents/application/services/
  • All application services receive data access through injected repository interfaces
  • Application layer services can be unit-tested without a real database
  • CI architecture check catches any future violations
  • All nox stages pass
  • Coverage >= 97%

Backlog note: This issue was discovered during autonomous operation
on milestone v3.7.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/adr-001-sqlalchemy-in-application-layer` - **Commit Message**: `fix(architecture): remove SQLAlchemy imports from application layer services` - **Milestone**: *(none — see backlog note below)* - **Parent Epic**: *(orphan — needs manual linking, see comment)* ## Bug Report **What was tested:** ADR-001 (Layered Architecture) compliance in the Application layer — specifically whether application services access the database through repository interfaces (ports) or directly through SQLAlchemy **Expected behavior (from ADR-001 and ADR-003):** ADR-001 states: > "The Domain Layer must have zero dependencies on infrastructure libraries (no SQLAlchemy imports, no LangChain imports, no HTTP client imports)." > "All service dependencies are wired through the DI container — no direct instantiation of infrastructure components in application or domain code." The Application layer should access data exclusively through repository interfaces (Protocol classes) defined in the Domain layer, with concrete SQLAlchemy implementations injected via the DI container. **Actual behavior:** Several Application layer services directly import SQLAlchemy, bypassing the repository pattern: ``` src/cleveragents/application/services/audit_service.py:50-51: from sqlalchemy import create_engine from sqlalchemy.orm import Session, sessionmaker src/cleveragents/application/services/phase_gating.py:14: from sqlalchemy.exc import OperationalError src/cleveragents/application/services/repo_indexing_persistence.py:28: from sqlalchemy.orm import Session src/cleveragents/application/services/lock_service.py:32-33: from sqlalchemy import delete, func, select from sqlalchemy.orm import Session ``` **Specific violations:** 1. `audit_service.py` creates its own SQLAlchemy engine and session factory directly — it should receive a repository via DI injection 2. `lock_service.py` imports and uses SQLAlchemy query primitives (`delete`, `func`, `select`) directly — this is infrastructure-level database access in the application layer 3. `phase_gating.py` imports `OperationalError` from SQLAlchemy — error handling for database-specific exceptions should be in the infrastructure layer 4. `repo_indexing_persistence.py` imports `Session` directly — should use a repository interface **Steps to reproduce:** ```bash grep -r "from sqlalchemy" src/cleveragents/application/services/ --include="*.py" ``` **Impact:** - Application layer is coupled to SQLAlchemy — swapping to a different ORM or database requires changes in the application layer - These services cannot be unit-tested without a real database (or complex SQLAlchemy mocking) - The hexagonal architecture's testability guarantee is broken for these services - ADR-003's DI container pattern is bypassed — these services create their own database connections **Fix:** 1. `audit_service.py`: Define an `AuditRepository` Protocol in the domain layer; inject it via DI container; move SQLAlchemy implementation to infrastructure 2. `lock_service.py`: Define a `LockRepository` Protocol; inject via DI; move SQLAlchemy queries to infrastructure 3. `phase_gating.py`: Catch generic exceptions in the application layer; let the repository implementation handle SQLAlchemy-specific errors and translate them to domain exceptions 4. `repo_indexing_persistence.py`: Inject a repository interface rather than a raw Session ## Subtasks - [ ] Define `AuditRepository` Protocol in domain layer - [ ] Move `audit_service.py` SQLAlchemy code to infrastructure repository implementation - [ ] Define `LockRepository` Protocol in domain layer - [ ] Move `lock_service.py` SQLAlchemy code to infrastructure repository implementation - [ ] Update `phase_gating.py` to catch domain exceptions instead of SQLAlchemy exceptions - [ ] Update `repo_indexing_persistence.py` to use repository interface - [ ] Register new repositories in DI container - [ ] Update unit tests to use mock repository implementations ## Definition of Done - [ ] Zero `from sqlalchemy` imports in `src/cleveragents/application/services/` - [ ] All application services receive data access through injected repository interfaces - [ ] Application layer services can be unit-tested without a real database - [ ] CI architecture check catches any future violations - All nox stages pass - Coverage >= 97% --- > **Backlog note:** This issue was discovered during autonomous operation > on milestone v3.7.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
Author
Owner

⚠️ Orphan Issue — Needs Manual Parent Epic Linking

This issue was created by an automated agent and could not be automatically linked to a parent Epic. No existing open Epic was found that clearly covers ADR-001 / hexagonal architecture compliance enforcement in the application layer.

Action required: A project maintainer should link this issue to the appropriate parent Epic using Forgejo's dependency system. The child issue (#4060) should block the parent Epic (i.e., the parent Epic cannot be marked complete until this issue is resolved).

Suggested candidates for parent Epic (please review and link the most appropriate one):

  • An existing or new Epic covering "Architecture Compliance / ADR Enforcement"
  • #2810 — Epic: CI Quality Gates Restoration (if a CI architecture check is in scope)
  • #362 — Epic: Security & Safety Hardening (if architectural integrity is in scope)

To create the dependency link manually via the Forgejo UI: open the parent Epic → Dependencies section → add this issue (#4060) as a dependency.


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

⚠️ **Orphan Issue — Needs Manual Parent Epic Linking** This issue was created by an automated agent and could not be automatically linked to a parent Epic. No existing open Epic was found that clearly covers ADR-001 / hexagonal architecture compliance enforcement in the application layer. **Action required:** A project maintainer should link this issue to the appropriate parent Epic using Forgejo's dependency system. The child issue (#4060) should **block** the parent Epic (i.e., the parent Epic cannot be marked complete until this issue is resolved). Suggested candidates for parent Epic (please review and link the most appropriate one): - An existing or new Epic covering "Architecture Compliance / ADR Enforcement" - **#2810** — Epic: CI Quality Gates Restoration (if a CI architecture check is in scope) - **#362** — Epic: Security & Safety Hardening (if architectural integrity is in scope) To create the dependency link manually via the Forgejo UI: open the parent Epic → *Dependencies* section → add this issue (#4060) as a dependency. --- **Automated by CleverAgents Bot** Supervisor: UAT Testing | Agent: ca-new-issue-creator
Author
Owner

Duplicate of #3924

This issue covers Application layer services directly importing SQLAlchemy (a specific form of infrastructure coupling). Issue #3924 was filed earlier (2026-04-06T07:28:52Z vs this issue at 2026-04-06T09:45:07Z) and covers the broader problem of Application services directly importing concrete infrastructure classes (repositories, models, sandbox, AND SQLAlchemy). The SQLAlchemy-specific violations in this issue are a subset of the violations documented in #3924. Closing as a duplicate — please track the fix in #3924.


Automated by CleverAgents Bot
Supervisor: UAT Testing | Agent: ca-uat-tester

**Duplicate of #3924** This issue covers Application layer services directly importing SQLAlchemy (a specific form of infrastructure coupling). Issue #3924 was filed earlier (2026-04-06T07:28:52Z vs this issue at 2026-04-06T09:45:07Z) and covers the broader problem of Application services directly importing concrete infrastructure classes (repositories, models, sandbox, AND SQLAlchemy). The SQLAlchemy-specific violations in this issue are a subset of the violations documented in #3924. Closing as a duplicate — please track the fix in #3924. --- **Automated by CleverAgents Bot** Supervisor: UAT Testing | Agent: ca-uat-tester
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#4060
No description provided.