← Blog

Architecture decision records work. They just don't cover the decisions that break you

ADRs are the standard answer to "why did we build it this way?" They capture technology choices well and miss the business rules that nobody thought of as architecture.

AppThentic Engineering · 6 min read
On this page

A team adopts architecture decision records. Within a quarter there are a dozen of them, each tidy and dated: why the queue is Kafka, why the service is split in two, why the database is Postgres. It is good practice and it helps.

Then someone asks why orders above a certain amount wait for a manual check, and there is no record. The decision was made in a meeting about fraud losses, years before the team had a template. It was never architecture, so it never got an ADR.

This is the gap. ADRs answer one kind of “why” well. The “why” that causes the most trouble is a different kind.

What is an architecture decision record, and what is it good at?

Michael Nygard proposed the format in a 2011 blog post. Each record is short and describes one decision using a few fixed sections: a title, the context and forces behind the decision, the decision itself, its status (proposed, accepted, deprecated or superseded) and its consequences. Martin Fowler’s later write-up adds two habits worth copying: keep records short, and when a decision changes, link to a new record that supersedes the old one instead of editing history.

That design is sound. It records the reasoning at the moment it is fresh, it keeps the options that were rejected, and it keeps a trail when the answer changes. Thoughtworks and several government engineering teams recommend keeping the records in source control, next to the code they explain.

For choices about technology and structure, nothing in this article argues against that.

Why do teams stop writing them?

Practitioner write-ups on ADRs repeat the same failure modes, and most of them are about process, not format:

  • No operating model. A team picks a template, writes a handful of records, then stops, because nobody decided when a record is required, who reviews it, or where it fits the workflow.
  • Poor discoverability. Records kept in a wiki that engineers rarely open do not get read at the moment of a decision.
  • Wrong scope. Records for trivial choices bury the few that matter, and the log fills with noise.
  • Manual upkeep. Status fields drift when someone has to remember to update them.

These are mostly blog posts and team retrospectives, not controlled studies, so treat “nobody reads them” as a common report and not a measured rate. The pattern is consistent enough to plan around.

Which decisions never get an ADR?

Look at what an ADR trigger usually is. An engineer is about to choose a framework, a storage layer, a service boundary. The decision is expensive to reverse, so someone writes it down.

Now look at where production behaviour actually surprises people:

  • A refund window of 30 days.
  • A 24-hour hold before a seller is paid.
  • A manual review above a set order value.
  • An override that applies in one region during one season.

These are business rules. Someone decided them, usually in a conversation with finance, risk, legal or a partner. An engineer then wrote a condition in code, often in an afternoon. Nobody called it a decision. It was a ticket, and the ticket said “set limit to 30.”

So the rules that cost the most to get wrong are the ones least likely to have a record. They rarely meet the “architecturally significant” bar, they are made by people who do not write ADRs, and they get implemented as a single if. The reason stays with the people in the meeting.

Why can’t we just write ADRs for business rules too?

Teams try. It runs into three problems.

The author is not the owner. The engineer who implements a rule is rarely the person who decided it. An ADR written by the implementer records what they were told, which may be a summary of a summary. The reason lives with the product, risk or finance owner, who has no reason to open a repository.

The volume is different. A healthy ADR log is small. Some practitioners suggest a few meaningful records per team per year. A mature system can hold hundreds or thousands of business rules. A process built for rare decisions does not scale to that, and the attempt produces the noisy, ignored log that teams are trying to avoid.

Most of the rules already exist. ADRs are written forward, at the moment of a decision. A system that has run for six years already holds a large set of rules whose reasons were never written. A forward-looking habit does nothing for them. The backlog of undocumented reasoning is exactly what hurts at the first incident, audit or migration.

What does a record need to stay trustworthy?

The best idea in the ADR tradition is that a record should say how current it is. A superseded status stops a stale record from being read as present truth. Business rules need that and a little more.

For a reason to be safe to rely on, a reader needs to know:

  1. What the rule is and where it lives, including every place it appears. A rule is often in the service, a config, the support script and the terms of service.
  2. Why it exists, in the words of the person who decided.
  3. Who owns it now, not who owned it when it was written.
  4. How sure anyone is. A reason the owner confirmed is different from a guess reconstructed from a commit message.
  5. Whether it is still true. The code may have changed since the reason was recorded.

Points 4 and 5 are where a hand-maintained log struggles. The status field says “accepted” because nobody has changed it, not because anybody has checked.

Where does organizational memory fit?

A set of ADRs and a set of business-rule records do different jobs, and they work best side by side. Keep writing ADRs for architecture. For business rules, the missing piece is a way to find the rules that already exist, ask the right owner why, and keep the answer attached to the rule.

That is what AppThentic does. According to the docs, it reads a company’s code and finds the business rules in it, signals such as conditions on money, time, who and state. It then finds the owner and asks short, specific questions anchored in the real code, such as “why 30 days and not 60?” The answers are kept as Organization Memory, each with its source, owner, date and status.

Several features line up with the lessons from ADRs:

  • Status is explicit. Each fact carries one of seven statuses: Observed, Documented, Inferred, Approved, Disputed, Stale or Unknown. An Inferred reason is labelled as AppThentic’s reading, and Approved means the owner confirmed it.
  • History is kept, not overwritten. Per the docs, each rule keeps a timeline of what it was, why, who approved it and what changed. This is the same instinct as superseding an ADR instead of editing it.
  • Staleness is detected. When a pull request changes a rule, or two locations disagree, or the owner leaves, the rule is marked Stale and the owner gets a specific question. See keeping answers current.
  • Existing reasoning is used. The docs say AppThentic reads commits, pull requests, tests and tickets for reasoning already written down, so decisions captured in an ADR or a good pull request are evidence, not duplicated effort.

Neither tool replaces the other. An ADR explains why the architecture is shaped as it is. A record of a business rule explains why the system treats a customer one way and not another, and what else breaks if that changes. See change impact.

What can a team do this week?

Pick one area where rules change often: refunds, pricing, credit, payouts. List the ten rules that matter most. For each one, write down two things: where the reason is recorded, and who could explain it today.

If the answer to the first is “an ADR” for most of them, your process is working. If it is “nobody wrote it down” or “I think Priya knew,” you have found the decisions your ADR practice does not reach. They are also the ones to capture before the person who remembers moves on. The same logic applies when the only engineer who understands a system leaves and when documentation goes stale.