Write the decision before the code: how Graphy uses ADRs to guide AI coding assistants
We moved the engineering effort from writing code to writing down decisions. Here is the format, why we do it, and thoughts on where the process could be improved.
5 min read
Featured image

Before we ask a coding assistant to implement a feature in Graphy’s charting SDK, an engineer writes down the decisions behind it. We explain how it should behave, the constraints it must respect and the approaches we’ve ruled out.
We keep these in architecture decision records, or ADRs (as described by Michael Nygard in 2011). Each is a short document about one engineering decision, stored alongside the code. The assistant uses it during implementation, and the team reviews it in the same pull request as the code.
Unlike a product requirements document (PRD), which describes what a feature should do and why it’s needed, an ADR records an engineering decision about how it will work and why we chose that approach.
We decided we wanted our assistants to have those decisions in front of them before choosing how to approach a task. As it turns out, a lot of “the assistant misunderstood me” moments we’d been experiencing simply came down to decisions we’d made, but never written down.
An example
One feature in our SDK lets people select parts of a chart by clicking or tapping them. We had to decide how the code would identify what they’d pressed.
The chart already keeps track of what the mouse is pointing at, so reusing that information for clicks might seem reasonable. But the saved information can be out of date: a quick mouse movement followed by a click can happen before it updates. A tap on a phone may have no earlier mouse movement to record at all.
So rather than describing the outcome we wanted, i.e “Let people select a bar”, we wrote down a rule: check the chart at the position of each press, as it happens. Don’t rely on the saved hover state.
That gives the assistant both a rule to implement and a reason to avoid the tempting shortcut. Someone reading the record later can see why we chose it, too.
What goes in an ADR
Our records have four main sections:
Context: the problem we’re solving, the constraints and any earlier decisions it depends on.
Decision: the rules the implementation must follow, with a reason for each.
Consequences: what improves, what changes for developers using the SDK, and the costs we’re accepting.
Considered alternatives: the approaches we rejected and why.
For the selection feature above, reusing the saved hover state goes in the alternatives. The timing and touch constraints sit beside it. An engineer or assistant can check that reasoning before proposing the same approach again.
Some of our ADRs include diagrams to show the cases the implementation needs to handle.

From our hover-detection ADR: what the chart should identify when the pointer is on, near or between shapes.
We keep the Decision section focused on the required behaviour and interfaces. An early draft included code sketches to illustrate the design, and the assistant implemented them. We learned that even an example can be read as a requirement.
How we use ADRs day to day

An engineer drafts the ADR with an assistant’s help. The assistant can explore the codebase, find related decisions and challenge the proposed rules. We work through the design before asking it to implement the feature.
During implementation, the assistant has the ADR, the earlier records it links to, a glossary of our domain terms and a review checklist. That gives it the decision, the vocabulary we use in the code and the conventions we expect it to follow. The assistant drafts, the engineer steers, and both check the result against the record.
The ADR and the code go into one pull request, so reviewers can question the decision itself as well as how the code implements it. If review changes the design, we update both there. The rejected approach joins the alternatives with its reason.
We also write tests for the rules we can assert. For the selection rule example, one test presses the chart without any previous pointer movement and checks that the expected group is selected. We also use Storybook, where reviewers can interact with real charts and try cases beyond the tests.
Building and testing often expose a decision we hadn’t thought to make. We go back to the record and work through it. After merge, we date amendments to an existing decision; a separate question gets a new ADR. Traditionally, a changed decision gets a new ADR that supersedes the old one. We update ours in place so the assistant doesn’t have to read several files to work out which rules still apply. The document describes the current design, and Git keeps the earlier wording for reference.
The next person gets the reasoning too
We’re a small, fully remote team. More work happening with assistants means more decisions happening in parallel. We can’t be on a call every time two pieces of work overlap, and a decision buried in a chat thread is hard to find a week later.
The ADR gives the next engineer, or the next assistant session, a place to find out why something works the way it does.
For example, we decided to hide a bar chart’s colour legend when it repeats the categories already labelled on the axis. We considered an exception for developers who explicitly set the legend’s position, but rejected it for the same reason: the legend would still repeat the axis wherever it appeared.
That reasoning stays with the code. Someone changing legends can read it before changing the behaviour, and a reviewer can challenge the decision in one place.
What we still need to work out
When we started using ADRs, we were rebuilding an existing product, so we already knew much of what we wanted to build. We also had engineers who understood the codebase and its weaknesses. Written decisions help us agree how a feature should behave, but they cannot establish which features customers need.
We’ve noticed fewer mistakes caused by constraints we’d left unwritten, but we haven’t measured the improvement or run a controlled comparison. We can’t say how much time this saves (though we’d love to measure it and show it on a chart).
A reviewer checking code against a decision record can still miss a problem nobody anticipated. We still need tests, exploratory review and engineering judgement. We also have to keep the records up to date as decisions change.
We think that work is worth it. ADRs give engineers and coding assistants the same decisions to build from, with reasons they can question.
If you want to try this, pick one decision in your next feature. Write down the rule, its reason and an approach you’ve ruled out before asking the assistant to build it. Review that record alongside the code, and change both when you learn something new.
Image
WRITTEN BY
Jaume Nicolau Prohens
Senior Full-Stack Developer
Jaume is a senior full-stack developer at Graphy, working across the charting SDK and Graphy Agents. His projects range from deterministic data systems to turning a heatmap into a playable version of DOOM.

