Auditing an architecture with an agent: what an LLM sees that static tools don't

A tool like dependency-cruiser is very good at detecting a dependency cycle. What it can't do is answer the question a client or a recruiter actually asks: is this codebase healthy, and if not, where should I start? That gap, between the raw metric and the decision to make, is what I wanted to close with Hexray, a command-line tool that audits a TypeScript or Kotlin architecture.
What the tool detects, no agent involved#
Hexray relies on classic static analyzers to produce four families of results:
| Check | What it detects |
|---|---|
| Layering violations | The domain imports an infrastructure dependency |
| Dependency cycles | Two modules depend on each other, directly or indirectly |
| Test pyramid ratio | Too many slow integration tests, not enough fast unit tests |
| Dependency freshness | Packages significantly behind their latest version |
So far, nothing requires AI: this is exactly what dependency-cruiser does, applied to a real project. The difference starts after.
Where the agent steps in: synthesis, not detection#
The agent's job is never to decide whether a dependency cycle exists. That's a fact, produced by a deterministic tool, not an opinion. The agent's job is to take that list of raw facts, prioritize it by severity, and rephrase it into an executive summary understandable without knowing the name of the underlying static analysis tool.
domain/
Finding, severity-based prioritization (no external dependency)
application/
RunAudit (use case), StaticAnalyzerPort (port)
infrastructure/
Concrete adapters: dependency-cruiser, Claude for synthesis,
HTML report generator
presentation/
CLI entry point
This separation isn't incidental, it protects against the main risk of an AI-assisted audit: the model inventing a finding that doesn't exist. StaticAnalyzerPort guarantees that every violation cited in the final report comes from a deterministic tool, never from a hallucination by the synthesis model. The agent never sees the source code directly, only the list of findings already produced.
A concrete example of what this changes#
A raw list says: "12 layering violations, 3 dependency cycles, pyramid ratio 15/60/25." An executive summary says: "The billing domain directly imports the payment HTTP client in three places, making it impossible to test billing logic without mocking an external service: this is the riskiest point to fix before adding a new feature." The second version requires business context that dependency-cruiser doesn't have and doesn't need to have: that isn't its job.
What this changes in practice#
Without the synthesis layer, an audit report stays an artifact for developers: useful, but unreadable outside the technical team. With it, the same audit becomes a deliverable a client or a recruiter can read in seconds, with a prioritized recommendation rather than a flat list. The general lesson goes beyond the tool itself: an agent adds the most value when you hand it exactly what an LLM does well, synthesizing and prioritizing, and none of what a deterministic tool already does better, detecting and counting.


