Most teams ship code and call it done. The architecture lives in someone's head, gets re-derived from grep on the third week of onboarding, and quietly drifts as people leave. That is the failure mode I have seen most often in production .NET systems — not bad code, but no shared model of why the code is the way it is.
If you take only one thing from this post: architecture is a deliverable, on the same level as the API and the database schema. It ships with the system or it does not exist.
What that looks like in practice
For every non-trivial service, I aim to ship four artifacts alongside the code:
- A C4 diagram — context and containers at minimum, components for the parts that matter. Kept in the repo, generated from text (Structurizr, Mermaid, PlantUML — pick one and stick with it).
- ADRs for the decisions that future-you will want to argue with. Auth model, persistence boundary, CQRS-or-not, sync-or-async — these are the ones that get re-litigated every six months until someone writes them down.
- A runbook for the on-call — wake-me-at-3am paths, common alarms, what each one means, what to check first.
- An onboarding doc — how to get the service running locally in under 30 minutes. If a new hire cannot run it, your architecture is theoretical.
None of these need to be long. A good ADR is two pages. A good runbook is a checklist. The point is that they exist, they are versioned with the code, and they are kept honest.
Why diagrams beat folder structure
A clean folder structure is necessary but not sufficient. It tells you what is in the system; a diagram tells you how the parts talk and why the boundaries are where they are. The same folder structure can serve very different architectures — strangler fig, modular monolith, full microservices — and folders alone will not tell you which one you are looking at.
The diagram is the contract between humans. When the code drifts from the diagram, you have a decision: update the code or update the diagram. Both are fine. Pretending the conflict does not exist is not.
ADRs are not ceremony
An ADR is not "we held a meeting and here is the writeup". An ADR is:
- Context — what is the situation, what are the forces?
- Decision — what did we pick, in one sentence?
- Consequences — what does this lock us in or out of?
That is it. Three sections, two pages, and a date. The value is in the consequences section — naming the trade-offs you accepted on purpose so the next engineer understands the budget you spent.
What this buys you
When architecture is a deliverable:
- Onboarding accelerates. A new senior can be productive in a week instead of a month.
- Decisions don't get re-litigated. "We chose CQRS for the order service because…" is a paragraph, not a meeting series.
- Drift becomes visible. You can see the gap between the design and the running system, and decide what to do about it.
- Stakeholders trust the system. Showing a clean C4 model to a non-technical sponsor closes more deals than any demo I have ever given.
The cost is small — maybe 5 to 10 percent of total engineering time — and it compounds. The teams I have seen that invest in this stay legible to themselves. The ones that do not turn into systems that only their original authors can maintain, and only barely.
If you take architecture seriously as a deliverable, the rest of the engineering practice tends to follow.