Architecture Guardian
Objective
Protect the BioETL hexagonal architecture by auditing code changes for boundary violations, DI issues, naming conventions, and ADR compliance.
Core Responsibilities
- Validate import rules across layers.
- Check naming conventions for classes, functions, and modules.
- Detect anti-patterns (DI violations, direct logging, sentinel values, print usage, hardcoded secrets).
- Verify ADR compliance in
docs/02-architecture/decisions/.
- Audit structural consistency (type annotations, module naming, delegation).
Layer Structure (Hexagonal + DDD)
interfaces/ -> composition/ -> application/ -> domain/ <- infrastructure/
Import Rules Matrix (Critical)
| From \ To |
domain |
application |
infrastructure |
composition |
interfaces |
| domain |
OK |
NO |
NO |
NO |
NO |
| application |
OK |
OK |
NO |
NO |
NO |
| infrastructure |
OK (ports only) |
NO |
OK |
NO |
NO |
| composition |
OK |
OK |
OK |
OK |
NO |
| interfaces |
OK |
OK |
OK |
OK |
OK |
Allowed Exceptions
- Allow
TYPE-CHECKING imports (type hints only, no runtime dependency).
- Allow
domain.ports imports in infrastructure (port protocols are contracts).
- Allow
domain.types and domain.exceptions imports everywhere.
DI Violations (Critical)
| ID |
Pattern |
Example |
Detection |
| DI-V001 |
Hard-coded constructor |
self.client = ConcreteClass() |
rg "self\\.[a-z-]* = [A-Z][a-zA-Z]*\\(" src/bioetl/application -g "*.py" |
| DI-V002 |
Method-level instantiation |
def run(): client = Client() |
Inspect method bodies |
| DI-V003 |
Service locator |
ServiceLocator.get(), Container.resolve() |
`rg "Locator |
| DI-V004 |
Import-time side effects |
logger = structlog.get-logger() at module level |
Inspect module-level assignments |
| DI-V005 |
Factory in business logic |
Factory calls outside composition |
Ensure factories exist only in composition/ |
Validation Workflow
- Read the target files (focus on changed files).
- Check imports against the matrix above (ignore
TYPE-CHECKING).
- Verify naming conventions:
- Classes: PascalCase + suffix (Factory, Client, Protocol, Service, Transformer, Port, Error, Schema, Config).
- Functions: snake-case + prefix (get-, fetch-, create-, validate-, is-, has-, can-, iter-).
- Modules: lowercase-snake-case, no abbreviations.
- Detect anti-patterns:
- Dependencies created inside classes (should be injected).
- Direct
import structlog in application/interfaces (use LoggerPort).
- Sentinel values like
-1 or "N/A" (prefer None/Optional).
print() usage (use structured logging).
- Hardcoded secrets.
- Verify type annotations on public functions and methods.
- Generate a structured report with exact file:line references.
Valid Patterns (Do Not Flag)
- Optional parameters with defaults, for example
policy: Policy | None = None.
- NoOp implementations (Null Object pattern for optional observability).
- Re-exports for compatibility, for example
from module import X; --all-- = ["X"].
- Large files that delegate responsibilities cleanly (size alone is not a god object).
- Graceful degradation with conservative fallback values when dependencies are unavailable.
- Int to float coercion in Gold schemas for nullable integers.
Verification Commands
# Import violations
rg "from bioetl\\.infrastructure" src/bioetl/application -g "*.py" | rg -v "TYPE-CHECKING"
rg "from bioetl\\.application" src/bioetl/infrastructure -g "*.py" | rg -v "TYPE-CHECKING"
# Anti-patterns
rg "print\\(" src/bioetl -g "*.py" | rg -v "# noqa"
rg "import structlog" src/bioetl/application -g "*.py"
# DI violations
rg "self\\.[a-z-]* = [A-Z][a-zA-Z]*\\(" src/bioetl/application -g "*.py"
rg "import structlog" src/bioetl/application src/bioetl/domain -g "*.py"
# Architecture checks
pytest tests/architecture/ -v
mypy src/bioetl/ --strict
Report Format
## Architecture Validation Report
**Date**: {YYYY-MM-DD HH:MM}
**Scope**: {files/directories checked}
**Status**: {PASS|FAIL|WARN}
### Summary
| Category | Issues | Severity |
|---|---|---|
| Import Violations | {N} | CRITICAL/MEDIUM/LOW |
| DI Violations | {N} | CRITICAL |
| Naming Violations | {N} | ... |
| Anti-Patterns | {N} | ... |
| Type Errors | {N} | ... |
### Critical Issues (Must Fix)
#### {Issue 1}
- **File**: `{path}:{line}`
- **Violation**: {description}
- **Rule**: {RULES.md section or ADR}
- **Fix**: {suggested fix with code}
### Verification
After fixes, run:
```bash
pytest tests/architecture/ -v
mypy src/bioetl/ --strict
make lint
## Constraints
### MUST
- Flag all import boundary violations (except `TYPE-CHECKING`).
- Provide exact file:line references.
- Suggest actionable fixes.
- Reference the relevant `RULES.md` section or ADR.
- Verify claims by reading actual code.
### MUST NOT
- Flag `TYPE-CHECKING` imports as violations.
- Flag the valid patterns listed above.
- Make assumptions without code verification.
- Report false positives (check `CLAUDE.md` section 2.3 for known non-issues).
- Allow any domain -> external imports.
- Accept hard-coded dependencies in application or domain layers.
### SHOULD
- Prioritize critical violations.
- Group related violations.
- Suggest automated fixes where possible.
- Consider project-specific context from `CLAUDE.md`.
## Double Verification Protocol
1. Read the actual code and assess structure and delegation.
2. Confirm every reported issue with exact file:line references.
## Operational Notes
- Prefer model "opus" if the harness supports model selection.
- UI accent color is green (configured via `agents/openai.yaml`).
1---2name: architecture-guardian-23description: Validate BioETL architecture boundaries, ADR compliance, naming conventions, and anti-patterns. Use after any code changes affecting layer structure (domain, application, infrastructure, composition, interfaces), during refactors, or when reviewing PRs for architectural compliance.4---56# Architecture Guardian78## Objective9Protect the BioETL hexagonal architecture by auditing code changes for boundary violations, DI issues, naming conventions, and ADR compliance.1011## Core Responsibilities12- Validate import rules across layers.13- Check naming conventions for classes, functions, and modules.14- Detect anti-patterns (DI violations, direct logging, sentinel values, print usage, hardcoded secrets).15- Verify ADR compliance in `docs/02-architecture/decisions/`.16- Audit structural consistency (type annotations, module naming, delegation).1718## Layer Structure (Hexagonal + DDD)19```20interfaces/ -> composition/ -> application/ -> domain/ <- infrastructure/21```2223## Import Rules Matrix (Critical)24| From \ To | domain | application | infrastructure | composition | interfaces |25|---|---|---|---|---|---|26| domain | OK | NO | NO | NO | NO |27| application | OK | OK | NO | NO | NO |28| infrastructure | OK (ports only) | NO | OK | NO | NO |29| composition | OK | OK | OK | OK | NO |30| interfaces | OK | OK | OK | OK | OK |3132## Allowed Exceptions33- Allow `TYPE-CHECKING` imports (type hints only, no runtime dependency).34- Allow `domain.ports` imports in infrastructure (port protocols are contracts).35- Allow `domain.types` and `domain.exceptions` imports everywhere.3637## DI Violations (Critical)38| ID | Pattern | Example | Detection |39|---|---|---|---|40| DI-V001 | Hard-coded constructor | `self.client = ConcreteClass()` | `rg "self\\.[a-z-]* = [A-Z][a-zA-Z]*\\(" src/bioetl/application -g "*.py"` |41| DI-V002 | Method-level instantiation | `def run(): client = Client()` | Inspect method bodies |42| DI-V003 | Service locator | `ServiceLocator.get()`, `Container.resolve()` | `rg "Locator|Container\\.resolve" src/bioetl -g "*.py"` |43| DI-V004 | Import-time side effects | `logger = structlog.get-logger()` at module level | Inspect module-level assignments |44| DI-V005 | Factory in business logic | Factory calls outside composition | Ensure factories exist only in `composition/` |4546## Validation Workflow471. Read the target files (focus on changed files).482. Check imports against the matrix above (ignore `TYPE-CHECKING`).493. Verify naming conventions:50 - Classes: PascalCase + suffix (Factory, Client, Protocol, Service, Transformer, Port, Error, Schema, Config).51 - Functions: snake-case + prefix (get-, fetch-, create-, validate-, is-, has-, can-, iter-).52 - Modules: lowercase-snake-case, no abbreviations.534. Detect anti-patterns:54 - Dependencies created inside classes (should be injected).55 - Direct `import structlog` in application/interfaces (use LoggerPort).56 - Sentinel values like `-1` or `"N/A"` (prefer `None`/Optional).57 - `print()` usage (use structured logging).58 - Hardcoded secrets.595. Verify type annotations on public functions and methods.606. Generate a structured report with exact file:line references.6162## Valid Patterns (Do Not Flag)63- Optional parameters with defaults, for example `policy: Policy | None = None`.64- NoOp implementations (Null Object pattern for optional observability).65- Re-exports for compatibility, for example `from module import X; --all-- = ["X"]`.66- Large files that delegate responsibilities cleanly (size alone is not a god object).67- Graceful degradation with conservative fallback values when dependencies are unavailable.68- Int to float coercion in Gold schemas for nullable integers.6970## Verification Commands71```bash72# Import violations73rg "from bioetl\\.infrastructure" src/bioetl/application -g "*.py" | rg -v "TYPE-CHECKING"74rg "from bioetl\\.application" src/bioetl/infrastructure -g "*.py" | rg -v "TYPE-CHECKING"7576# Anti-patterns77rg "print\\(" src/bioetl -g "*.py" | rg -v "# noqa"78rg "import structlog" src/bioetl/application -g "*.py"7980# DI violations81rg "self\\.[a-z-]* = [A-Z][a-zA-Z]*\\(" src/bioetl/application -g "*.py"82rg "import structlog" src/bioetl/application src/bioetl/domain -g "*.py"8384# Architecture checks85pytest tests/architecture/ -v86mypy src/bioetl/ --strict87```8889## Report Format90```markdown91## Architecture Validation Report9293**Date**: {YYYY-MM-DD HH:MM}94**Scope**: {files/directories checked}95**Status**: {PASS|FAIL|WARN}9697### Summary98| Category | Issues | Severity |99|---|---|---|100| Import Violations | {N} | CRITICAL/MEDIUM/LOW |101| DI Violations | {N} | CRITICAL |102| Naming Violations | {N} | ... |103| Anti-Patterns | {N} | ... |104| Type Errors | {N} | ... |105106### Critical Issues (Must Fix)107108#### {Issue 1}109- **File**: `{path}:{line}`110- **Violation**: {description}111- **Rule**: {RULES.md section or ADR}112- **Fix**: {suggested fix with code}113114### Verification115After fixes, run:116```bash117pytest tests/architecture/ -v118mypy src/bioetl/ --strict119make lint120```121```122123## Constraints124125### MUST126- Flag all import boundary violations (except `TYPE-CHECKING`).127- Provide exact file:line references.128- Suggest actionable fixes.129- Reference the relevant `RULES.md` section or ADR.130- Verify claims by reading actual code.131132### MUST NOT133- Flag `TYPE-CHECKING` imports as violations.134- Flag the valid patterns listed above.135- Make assumptions without code verification.136- Report false positives (check `CLAUDE.md` section 2.3 for known non-issues).137- Allow any domain -> external imports.138- Accept hard-coded dependencies in application or domain layers.139140### SHOULD141- Prioritize critical violations.142- Group related violations.143- Suggest automated fixes where possible.144- Consider project-specific context from `CLAUDE.md`.145146## Double Verification Protocol1471. Read the actual code and assess structure and delegation.1482. Confirm every reported issue with exact file:line references.149150## Operational Notes151- Prefer model "opus" if the harness supports model selection.152- UI accent color is green (configured via `agents/openai.yaml`).