Your architecture docs are fiction
Not because anyone lied — because the code kept moving and the diagram didn't. The only complete, current description of the system is the source, spread across repos, languages and tiers.
- The C4 diagram was drawn three rewrites ago
- No single picture spans the frontend, the services and the database
- Nobody can state the true deployment topology from memory
- Coupling and blast radius are felt, not measured
- “Which service owns this table?” has no authoritative answer
- Every modernization estimate rests on a guess
C4 DRILL-DOWN
Five levels, aggregated from the real graph
Start at the system context and drill: Deployment topology, then project groups, then the
components inside a project, down to the file-level graph — each level rolled up from the same
linkGraph, symbolLinks and dataAccessGraph. Big estates stay
legible: a monorepo with a hundred projects folds into a handful of groups.
- Context → Deployment → Projects → Components → Code
- Laid out deterministically with a layered (Sugiyama) engine
- Components boxed by folder and role — controllers, services, data access, models — with the datastores outside
- The file hairball is scoped to one component, never the whole system
1 · Context1 system · 7 external2 · Deployment29 services · 71 edges3 · Projects179 → 8 groups4 · Componentsgrouped by role5 · Codefile graphDEPLOYMENT TOPOLOGY
Read from your deployment files, not a whiteboard
ClarifyDoc reads your docker-compose stacks, Kubernetes manifests, Dockerfiles and
Terraform modules and reconstructs services, externals and the edges between them — name-agnostic,
from real evidence. An API-key handshake between a provider and a consumer becomes an edge; a
literal connection string tells ownership from a cross-DB reference.
- A compose
build:reads its Dockerfile: the command it runs and the source file it starts - Terraform modules give Lambdas, API Gateway routes, queues, tables and databases
- Helm charts, and the Argo CD and Flux releases that deploy them
- A service’s outbound calls followed through its env and config files, dev proxies and gateways (YARP, Ocelot) to the service that answers
- CI pipelines’ deploy steps — GitHub, GitLab, Azure, CircleCI, Bitbucket — with trigger and path
- The environment variables each service reads, and which deployments set them (names only)
# docker-compose.yml — evidence
bff.api AUTH__APIKEY=${IDP_KEY}
auth.idp ApiKeys__0=${IDP_KEY} ← handshake
order.api Db=Host=postgres;Database=orders
# derived edges
bff.api ──api-key──▶ auth.idp (external)
order.api ──────────▶ postgres (orders)
ENTITY-RELATIONSHIP MODEL
One data model, recovered from the ORM code
Entities, fields, enums and associations are lifted straight out of EF Core, Mongoose, Prisma,
Eloquent, Hibernate, TypeORM and friends — plus raw CREATE TABLE DDL — with
cardinality and foreign keys as crow's-foot relationships. Raw SQL files parse into the same
model, so the picture holds even where there's no ORM.
- Associations with cardinality, FK and join tables
- SQL migration chains — Flyway, golang-migrate, Prisma — replayed in order into the schema they end with
- MyBatis mapper methods joined to the SQL in their mapper XML, and the tables it names
- Every entity ties back to the endpoints that touch it
Customers
- id uuid
- name text
- email text
Orders
- id uuid
- customer_id fk
- total money
- status enum
OrderLines
- id uuid
- order_id fk
- product_id fk
- qty int
Customers 1─* Orders 1─* OrderLines
ONE GRAPH, EVERY TIER
Cross-repo, cross-language, one model
ClarifyDoc detects project markers and assigns every file to its innermost sub-project — then keeps the links that cross those boundaries. A Delphi client, a .NET service and a React frontend become one analyzable system.
Detected from package.json, *.csproj, *.dpr, go.mod, pom.xml and more.
Frontend → backend → DB links survive across languages and repositories.
Every link is graded EXTRACTED / INFERRED / AMBIGUOUS.
Versioned by content hash — diff the architecture between two runs.
YOUR ARCHITECTURE, ENFORCED
Write the rules down once — every breach is named
Say which parts of the system must not depend on which, in a file committed with the code. Each import that breaks a rule is reported with the rule’s name — in the report, in the editor’s Problems panel and in the pull-request gate, which fails only on breaches the change introduces.
from/toglobs,exceptfor the shared kernel,warnorerror- Your own layer map, checked before the built-in heuristics
- Cycles judged without type-only imports, so an interface file doesn’t count as a tangle
// .clarifydoc/config.json
{
"rules": [
{ "name": "billing stays out of payroll",
"from": "features/billing/**",
"to": "features/payroll/**",
"except": ["**/shared/**"] },
{ "name": "domain is pure",
"from": "src/Domain/**",
"to": "src/Infrastructure/**",
"severity": "warn" }
]
}
Topology you can act on
Beyond the picture, the graph carries the structural signals you'd otherwise argue about from intuition.
Coupling & cohesion
Named communities, a module dependency matrix and cohesion scores show where the natural seams — and the tangles — actually are.
God-nodes
The files everything leans on, surfaced explicitly, so refactors start where they matter.
Layer violations
Imports that cross the boundaries your architecture — or your own rules file — says shouldn't be crossed.
Blast radius
Per-file and per-class change impact, so modernization is scoped from data.
Surprising connections
Edges between parts of the system that “shouldn't” know about each other.
Services and their contracts
Which service calls which, over HTTP, gRPC or a message queue — Kafka, AMQP, BullMQ, Celery — with the endpoints behind every edge.
Diagrams you can commit
clarifydoc export writes ARCHITECTURE.md, DATA-MODEL.md, FLOWS.md, Mermaid, GraphML, Cypher, CSV, an Obsidian vault, an OpenAPI document and a CycloneDX SBOM; in VS Code, Create Architecture Diagram does it in one command. The same code gives the same file, so the diff is the change — and facts --check fails a document whose cited facts no longer hold.
Deeper resolution, no Docker
In VS Code, the language servers you already run resolve the cross-file calls the text linker missed. In CI, the SCIP or LSIF index your pipeline already builds does the same.
Behaviour baselines
Commit every endpoint’s flow — calls, data, hops to other services — and fail the build when one changes. How it works →
IN THE REPORT
Where architects spend their time
Real screenshots of ClarifyDoc’s report on RealWorld’s open-source Conduit app. Each one opens that tab in the product tour.
GENERATE IT
From repos to a living architecture model
Run it on each repo from VS Code or in CI, and the model regenerates from the code every time — re-runs only re-read what changed. The report is one self-contained file, so the architecture travels with the change: attach it to the review, the ADR or the hand-over.
Architecture
Data Model
Data Flows
Insights