Keep the Approaches You Tried, Not Just the One You Picked

An architecture decision records the option you chose. The approaches you tested and rejected, and why, usually vanish. Approaches are now first-class in Specsource: candidate solutions with a lifecycle, promoted into a reusable org library, and versioned as the platforms underneath them change.

All posts

"Why didn't we just use X?" is one of the more expensive questions on a software project. Someone asks it in month four. The honest answer is usually good: we tried X, it fell over on the offline requirement, and Y was the one that survived the proof of concept. But that answer lives in the head of whoever ran the spike, and when they roll off the project it goes with them. The next person asks the same question, runs the same spike, and reaches the same conclusion a week later.

An architecture decision record fixes part of this. It captures the option you chose and, written well, the alternatives you weighed. But an ADR is a record of a decision: a single moment, written once, in prose. The candidates themselves, the three approaches you actually prototyped, shortlisted, ranked and dropped, are not first-class anywhere. At best they are bullet points inside someone's decision. Approaches change that.

What an approach is

An approach is a candidate way of solving something, captured as its own entity with a lifecycle:

proposed -> in PoC -> shortlisted -> planning -> adopted -> live -> retiring -> sunset
                                          \-> rejected

Each one carries the reasoning that normally evaporates the moment a choice becomes code: what makes it attractive, and where it breaks down. A rejected approach is not deleted. It keeps its status and its "why it does not work" note, so "we tried that" arrives with the receipt attached rather than as folklore.

Approaches and decisions are different things

It is worth being precise about how this sits next to an ADR, because they are easy to conflate. An ADR answers "what did we decide, and why". An approach answers "what are the options, and where does each one stand". They are built to connect. A decision links the approaches it is choosing between, and the decisions workspace lets you line them up side by side, the way a comparison table works on a shopping site, and rank them. The front-runner becomes the adopted approach, and the decision records the verdict. The ADR is the conclusion; the approaches are the working that led to it, kept rather than thrown away.

The same problem, the next project

Here is the part that pushed us from "approaches" to "an approaches library". Most of the genuinely hard approaches are not project-specific. How you isolate tenants in a multi-tenant database, how you keep a product catalogue in sync with Shopify, how you run background jobs without a dedicated queue: these recur on project after project. And every time, a team rediscovers what worked last time from memory, or worse, picks differently because the person who learned the lesson is on another account now.

So an approach can be promoted out of a single project into an org-level library that every project can draw on. Promoting copies the approach into the library and links the original back to it, so the provenance survives in both directions: this library entry came from that project, and that project is using this library entry. The next project that hits the same problem starts from a solution you have already proven, with its reasoning intact, instead of a blank editor.

Solutions rot when the platform moves

An approach is only valid against the platform it was built for, and platforms do not hold still. Shopify versions its APIs on a calendar and retires old versions every quarter. An approach that worked cleanly against the Storefront API a year ago can quietly stop being valid without a single line of your own code changing. This is the same reason the code is the cheap, disposable layer and the captured reasoning is the durable one: the ground moves underneath the implementation on a schedule you do not control.

So approaches are versioned, and each version carries platform-compatibility tags. A tag says whether the approach works with, requires, or is incompatible with a named platform at a given version:

works with         Shopify Storefront API   < 2025-04
incompatible with  Shopify Storefront API   >= 2025-04
requires           Node                     >= 20

When Shopify's 2025-04 release drops the field your sync relied on, you cut a new version of the approach with updated compatibility. The previous version stays as read-only history, the new one becomes current, and the family shows exactly when the solution changed and why. An approach stops being a single snapshot that silently goes stale and becomes a record of how a solution held up, and where it had to evolve, as the platform shifted under it.

Why this matters for the agents

There is a second reader for all of this now, and it is less forgiving than the first. An AI coding agent deciding how to implement something has the same gap as a new hire, but it fills the gap with a confident guess rather than a question. Left to itself it will reach for the obvious approach, including the one your team prototyped last year and rejected for a reason that is not visible in the code.

Because approaches are structured entities, an agent querying the project over MCP can read them before it writes anything: which approach was adopted, which were rejected and why, and which platform versions a given approach is actually valid against. That is the difference between an agent that reinvents a solved problem and one that builds on the solution you already landed on, against the platform version you are actually shipping to.

The roads you didn't take

An ADR tells you the road you took. The approaches library keeps the roads you did not, and the reason you turned back, and it does that across projects and across the platform versions that keep moving underneath you. The option you picked is rarely the whole story. The ones you ruled out, kept with their reasoning instead of left in someone's memory, are how a team stops paying for the same lesson twice.

Frequently asked questions