# 0001 — Hexagonal Architecture with DDD **Status:** Accepted **Date:** 2026-06-16 ## Context Archlens is a language-agnostic architecture diagram generator. It needs to support multiple input languages (Rust, C#, Python), multiple output formats (Mermaid, ASCII, future: D2, interactive web), and multiple IO strategies (file, stdout). The tool must be extensible without modifying core logic. ## Decision Use hexagonal architecture (ports and adapters) with DDD structuring. Workspace layout: ``` crates/ domain/ — zero external deps (no tracing, no rayon, nothing) application/ — depends on domain only + rayon, tracing (pragmatic utility exceptions) adapters/ tree-sitter/ — SourceAnalyzer (internal modules per language) walkdir/ — FileDiscovery mermaid/ — DiagramRenderer ascii/ — DiagramRenderer file-writer/ — OutputWriter stdout-writer/ — OutputWriter toml-config/ — ConfigLoader presentation/ — CLI (clap), composition root, tracing-subscriber setup ``` **Dependency rules:** - Domain depends on nothing - Application depends on domain - Adapters depend on domain (not application) - Presentation depends on application + adapters (composition root) **Use cases** are generic over port traits (static dispatch), not trait objects. **Pragmatic exceptions:** `rayon` and `tracing` in application crate. These are general-purpose utilities, not external system adapters. Documented explicitly to avoid precedent creep. ## Alternatives Considered - **Trait objects for DI:** Simpler type signatures but runtime dispatch overhead and less compile-time safety. Rejected — generics align better with Rust idioms and zero-cost goals. - **DI container (shaku):** Unnecessary ceremony for Rust. Manual wiring in presentation is explicit and sufficient. - **Domain with tracing dependency:** Rejected to keep domain fully pure. Application wraps domain calls in spans. ## Consequences - Adding a new language = new module in tree-sitter adapter (or new adapter crate) - Adding a new output format = new adapter crate implementing DiagramRenderer - Adding a new output destination = new adapter crate implementing OutputWriter - Use case type signatures carry multiple generic parameters (accepted tradeoff) - Domain crate is testable with zero setup — no mocks for infrastructure needed