Architecture

The Architecture Decision Record as the most underrated design artefact

Siddharth Rao · 8 min read

Every design process produces decisions. Most produce very little record of why those decisions were made, what alternatives were considered, or what the best argument against the chosen approach was and why it was rejected. That absence isn't a documentation problem — it's an intellectual honesty problem. When circumstances change, when a new team member asks why the system works the way it does, the decision is present in the code and the reasoning is nowhere.

The Architecture Decision Record, in its full form, captures the context that made a decision necessary, the decision itself, the alternatives considered and rejected, the consequences it carries, and — in the version I treat as essential — a direct rebuttal to the strongest objection that could be raised against it. That last field is what makes an ADR a design artefact rather than documentation. Anyone can write down what they decided. Writing down the best argument against your decision, and answering it honestly, requires having actually tested the decision before committing to it.

FieldWhat makes it incomplete
ContextStating the technical problem without the business or operational constraint that shaped the options.
Decision"We chose X." Full stop — without scope, the decision can't be used to evaluate future deviations.
Alternatives rejectedA list of names without reasons. "We considered Temporal.io but rejected it" references an evaluation that was never recorded.
ConsequencesListing only benefits. Every architectural decision creates constraints; an ADR that doesn't name them hasn't been honestly evaluated.
RebuttalA weak or strawman objection. The field only earns its place when the objection is strong enough that answering it required genuine reasoning.

I treat the Rebuttal field as required for any decision involving a meaningful trade-off — which is to say, any decision worth recording at all. Here's one, drawn from the orchestration layer of an autonomous deal desk pipeline, presented in full because the objection it had to survive wasn't a weak one.

ADR-001 · Vertex AI Agent SDK over custom ReAct implementation

Context. The orchestration layer requires a ReAct loop with tool-calling, state management, and retry handling. The system is GCP-native by requirement; portability to other clouds is not a defined business requirement for this deployment.

Decision. Use the Vertex AI Agent SDK — managed tool-call dispatch, turn-limit enforcement, structured memory, built-in tracing.

Rejected. LangGraph/LangChain — more portable, but requires manually implementing retry logic and quota enforcement the Agent SDK provides natively; the portability benefit isn't realised in a GCP-native deployment. Custom Python ReAct — maximum flexibility, but no managed observability or retry, increasing implementation surface by an estimated 40% without proportionate capability gain.

Consequences. Coupling to the Vertex AI ecosystem. Migration requires re-implementing the tool manifest and state model. Graph topology changes require Architecture Board review.

Rebuttal to primary objection. LangGraph is framework-agnostic and avoids GCP lock-in, which should be the default posture for any enterprise architecture. Architecturally valid as a general principle — but portability is not free, and its cost has to be evaluated against the actual deployment boundary. This system is GCP-native by design across every other layer: AlloyDB, Workload Identity, VPC Service Controls, Cloud KMS. The portability benefit of a framework-agnostic orchestrator is only realised if the rest of the stack is portable too. It isn't. Accepting portability at the orchestration layer while keeping GCP-specific infrastructure everywhere else is a false compromise — it adds the complexity of avoiding lock-in without delivering the benefit. If the deployment boundary changes, the correct response is to re-evaluate this ADR against the new constraint, not to pre-optimise for a requirement that doesn't yet exist.
If the objection is trivial, the decision was probably not a real trade-off.

What makes that record useful isn't that the decision was right. It's that the rebuttal had to establish something more specific than "Vertex AI is better" — it had to establish that accepting the lock-in was the correct trade-off given the actual deployment boundary, which is a different and more honest argument. A future reader disagreeing with ADR-001 doesn't have to reconstruct the reasoning from scratch. They have the objection already stated, in its strongest form, and the answer it had to survive.

That's the actual test for whether an ADR is doing its job: not whether the decision holds up forever, but whether someone six months from now, encountering the same trade-off under different constraints, has enough on the page to know exactly what changed and what didn't.

Further reading: Nygard, M. (2011). Documenting Architecture Decisions. Cognitect Blog. · Keeling, M. (2017). Design It! Pragmatic Programmers, Ch. 11. · The Open Group, TOGAF 10 Standard, Phase H. · Richards, M. & Ford, N. (2020). Fundamentals of Software Architecture. O'Reilly, Ch. 19.

← Back to all writing
— Siddharth Rao