Adhish P. Acharya
← Back to Blog

October 9, 2026

The Importance of Writing Down a Decision Before You Build It

architecturesoftware-engineeringdocumentationsystem-designadr

How I Got Here

I was starting work on a ticket to build a blog editor - letting the marketing team write and publish posts directly from the ERP, no developer needed. First thing I found: the ticket was blocked. It couldn't start until a decision about how the content gets stored was written down as an Architecture Decision Record (ADR), and that ADR didn't exist yet.

I checked the existing ADR log before writing anything. The team already had a solid set of them - covering other hard-to-reverse decisions across the codebase - just none covering this particular question. So writing it became the actual first task.

What Writing It Involved

An ADR is a short file kept next to the code, recording one significant decision and the reasoning behind it. The format is simple, and that simplicity is the point:

  • Context. The forces that make the decision necessary - facts only, not the choice itself.
  • Decision. One plain statement, specific enough that someone could act on it directly.
  • Alternatives considered. Every option that got rejected, with a one-line reason each.
  • Consequences. What gets easier, what gets harder, and a kill-criterion - a concrete, observable signal that would mean the decision was wrong.

A good ADR runs about two pages. Longer than that, and it's probably two decisions wearing one title.

Before writing any actual code, I stress-tested my own draft. I ran a pre-mortem - assumed the decision had already failed in production, and worked backward asking why.

What the Stress Test Caught

That's where it found something real.

There's a nightly cleanup job in the system that deletes any uploaded file nothing currently points to - a reasonable way to keep storage from filling up with orphaned uploads. My first draft of the decision tracked which images a blog post uses based on the draft alone, recalculated every time someone hit save.

Here's the gap: a published post is a separate snapshot from its draft. Remove an image from the draft and save - the record of "images this post uses" no longer lists it. But the already-published, live version of that post could still be showing that exact image. The cleanup job sees an upload nothing references anymore, and deletes it. The live page ends up with a broken image, and nothing anywhere logs an error. No crash, no failed request - just a silently broken image on a page a customer might be looking at.

The fix was one sentence added to the decision: an upload counts as "in use" as long as either the current draft or the latest published snapshot refers to it. That sentence exists only because the review happened before any code was written. It's also now the first entry in the ADR's kill-criterion - if a live post ever shows a broken image because of this cleanup job, that's the signal the decision needs revisiting.

Why This Actually Matters

The bug this caught is the kind that shows up quietly, a day or two after launch, on a page nobody's actively watching - not a crash, not a failed deploy, just a slowly eroding piece of content that erodes trust in the feature once someone finally notices.

Caught at the ADR stage, the fix cost one sentence. Caught in production, it costs a debugging session, an incident, and someone's afternoon spent figuring out why an image that was definitely there yesterday is suddenly gone.

That's really the whole argument for ADRs, stripped down: they move the moment of disagreement to the cheapest possible point. Arguing against a two-page document takes minutes. Changing a data model that's already shipped and in use takes weeks. Six months from now, a new engineer finds a design choice that looks a little odd - with an ADR, they read the log and understand why it's shaped that way, instead of either ripping it out and rediscovering the reason in production, or leaving it alone out of fear because nobody can explain it.

And because accepted ADRs are never edited - only superseded by a new one when the team changes its mind - the log stays an honest history. You can see not just what the team believes now, but what it used to believe, and exactly when and why that changed.

Why Teams Should Adopt This

Any team making decisions that are hard to reverse - a data model, an API contract, adding or removing a dependency, choosing between two genuinely viable technical approaches - benefits from writing the decision down before building it, not after.

A few habits are worth calling out, because they're what make ADRs actually work instead of becoming theater:

  • Write it before the code, not after. An ADR written after the fact turns into a justification exercise instead of a real decision - it stops catching anything, because the thing it would have caught already shipped.
  • List the downsides honestly. If the Consequences section has no negatives in it, the decision wasn't actually interrogated.
  • Never edit an accepted ADR. The moment you do, the log stops being trustworthy as history. A change of mind gets its own new ADR, explicitly superseding the old one.
  • Keep it short. Two pages is the target. Past that, it's probably two decisions that should be split apart.
  • Make it findable. Link ADRs from the pull requests that implement them, and keep an index somewhere obvious - a log nobody reads doesn't do much good.

Where the Detailed Decision Stands

The ADR this post is built around is for exactly the problem described above: how rich text content gets stored, validated, and rendered across the three places that each need to agree on it. It's currently marked Proposed, sitting on its own branch, waiting on review before it gets accepted into the codebase - which is also exactly how the process is supposed to work. The argument happens on a two-page document, not on a pull request with a thousand changed lines.

If a decision in front of you is genuinely hard to reverse, it's worth the price of a document before it becomes the price of an incident.