Choose an architecture and record why — constraints before options, reversibility as the ranking axis, at least one option that extends what already exists, and an ADR that survives the people who wrote it. Use when a feature needs a shape rather than a file, when picking between services, stores or patterns, or when someone asks "how should we build this?"
Architecture is the set of decisions that are expensive to change later. The
job is to work out which decisions those are, make them deliberately, and leave
a record that answers "why is it like this?" in two years.
1. Write the constraints before the options
An option that violates a constraint is not an option, and listing it wastes
everyone's afternoon. So the constraint list comes first:
Kind
Examples
Fixed
A regulation, an integration that already exists, a contract, a hard date
Operational
Who is on call, what the team can actually run, the deploy cadence
Economic
Budget, and what it costs when idle — not just at peak
Data
Volume, growth, retention, residency, what must never be lost
Team
What this team already knows, and how many people will maintain it
The team constraint is the one most often left out and most often decisive. An
architecture nobody on the team can debug at 2am is the wrong architecture,
whatever its other properties.
2. Rank by reversibility, not elegance
Sort every decision into one of two piles, and spend your attention accordingly:
One-way doors. Data model, the storage engine, the public API shape,
tenancy model, the auth model, anything users will build on. These get the
scrutiny, the prototype, and the written decision.
Two-way doors. Which library, how a module is split, the queue
implementation, most naming. Decide quickly, move on, change it later when you
know more.
Teams reliably spend their deliberation on two-way doors, because those come
with strong opinions, and rush the one-way doors, because those feel abstract.
Watch for it.
3. At least three options, and one of them extends what exists
Extend what is already here. Always evaluate this properly. It is
frequently the right answer and is skipped because it is unexciting. If you
reject it, say why in one sentence — that sentence is the justification for
everything the new thing will cost.
The straightforward new build. The obvious shape, done plainly.
The one that is right if a constraint changes. Usually the one that scales
further or costs more. Naming it makes the trade explicit rather than
implicit.
For each: what it costs to build, what it costs to run, what it costs to
operate, what it makes easy later, and what it makes hard later. That last
column is the one that predicts regret.
4. Boring by default; spend novelty once
Every unfamiliar technology has a cost that does not show up in the comparison
table: nobody knows its failure modes, its operational surprises, or how to
debug it under pressure. That cost is real and it is paid at the worst moment.
Allow yourself one interesting choice per project, in the place where it buys
the most. Everything else is the thing the team already runs.
A good test: for each component, who on the team could fix it if it broke on a
Friday evening? If the answer is "the person who chose it", that is the risk,
stated.
5. Design the failure, not just the success
For each option, walk the failure paths before deciding:
What happens when the dependency is down? Slow is worse than down — plan for
slow.
What happens on a partial write, a retry, a duplicate delivery?
What is the blast radius of one bad record, one bad deploy, one bad tenant?
How does it behave at zero, at one, and at a hundred times the expected load?
How do you know it is broken — what emits the signal, and who sees it?
How do you recover, and has anyone tried?
An architecture diagram with no failure annotations is a sketch of the happy
path.
6. Cost and operations are design, not an afterthought
Idle cost. Many systems spend most of their life idle. What does this cost
doing nothing? Pay-per-use and scale-to-zero change the shape of what is
affordable, at the price of a cold start you must then design around.
Cost that scales with the wrong thing. Per-request, per-GB-scanned and
per-connection pricing all punish a specific mistake. Know which one you are
exposed to.
Who gets paged, for what, and what they can do about it at that hour.
What the deploy looks like, including the rollback.
What you will need to debug it — logging, tracing and a way to answer
"what happened to this one record?" without a database console.
7. Draw the boundaries, and be honest about them
The valuable part of a diagram is the lines, not the boxes. For each boundary:
What crosses it, in what format, and who owns that format?
Is it synchronous or asynchronous, and what happens when the far side is slow?
Is it a real boundary, or a folder pretending to be one? A "service" that
shares a database with another service is one service with extra latency.
Prefer few, well-defined boundaries over many convenient ones. Every boundary is
a place where versions drift, and drift is expensive — see contract-change.
8. Write the ADR
One file per significant decision, in the repo, numbered and dated. Short.
# ADR-014: Store submissions as immutable versions rather than editing in place
**Status:** Accepted · 2026-09-21 · Supersedes ADR-009
**Context**
Submissions reference a template that authors keep editing. Completed records
no longer match what the user saw. ~2% of records affected in the last quarter.
**Decision**
Publishing snapshots the template into a numbered immutable version. Records
store the version id at creation and read through it for their lifetime.
**Consequences**
+ Historical records stay readable; scores are reproducible.
+ The version diff becomes the changelog for free.
- Every typo fix creates a version; the version table grows.
- Readers must resolve through the record's version, including exports.
**Rejected**
- Edit in place with an audit log — does not make old records renderable.
- Copy the whole template onto each record — 40x storage, no diffing.
**What would reverse this**
If templates stop being editable after first use, versioning is unnecessary.
The decision is stated as a claim, not a topic. "ADR-014: Versioning" tells
a future reader nothing; the sentence above tells them everything.
Rejected options and what would reverse it are the two sections people skip
and the two that stop the same debate being re-run every year.
9. Say what you are not building
The architecture's non-goals are as load-bearing as the requirements' non-goals:
no multi-region, no offline, no real-time, single tenant per database, English
only. Each of these is a decision someone will otherwise assume went the other
way.
Checklist
Constraints written before options, including team and operational
Decisions sorted into one-way and two-way doors; scrutiny spent on one-way
Extending what exists evaluated properly and rejected in writing if rejected
Each option carries what it makes hard later, not only what it makes easy
At most one unfamiliar technology, and someone other than its champion can debug it
Idle cost, paging, deploy and rollback considered part of the design
Boundaries real, few, and owned
ADR written with the decision as a claim, plus rejected options and what would reverse it
Architectural non-goals stated
1---2name: solution-architecture3description: Choose an architecture and record why — constraints before options, reversibility as the ranking axis, at least one option that extends what already exists, and an ADR that survives the people who wrote it. Use when a feature needs a shape rather than a file, when picking between services, stores or patterns, or when someone asks "how should we build this?"4---56# Solution architecture78Architecture is the set of decisions that are expensive to change later. The9job is to work out which decisions those are, make them deliberately, and leave10a record that answers "why is it like this?" in two years.1112## 1. Write the constraints before the options1314An option that violates a constraint is not an option, and listing it wastes15everyone's afternoon. So the constraint list comes first:1617| Kind | Examples |18|---|---|19| **Fixed** | A regulation, an integration that already exists, a contract, a hard date |20| **Operational** | Who is on call, what the team can actually run, the deploy cadence |21| **Economic** | Budget, and what it costs when idle — not just at peak |22| **Data** | Volume, growth, retention, residency, what must never be lost |23| **Team** | What this team already knows, and how many people will maintain it |2425The team constraint is the one most often left out and most often decisive. An26architecture nobody on the team can debug at 2am is the wrong architecture,27whatever its other properties.2829## 2. Rank by reversibility, not elegance3031Sort every decision into one of two piles, and spend your attention accordingly:3233- **One-way doors.** Data model, the storage engine, the public API shape,34 tenancy model, the auth model, anything users will build on. These get the35 scrutiny, the prototype, and the written decision.36- **Two-way doors.** Which library, how a module is split, the queue37 implementation, most naming. Decide quickly, move on, change it later when you38 know more.3940Teams reliably spend their deliberation on two-way doors, because those come41with strong opinions, and rush the one-way doors, because those feel abstract.42Watch for it.4344## 3. At least three options, and one of them extends what exists4546- **Extend what is already here.** Always evaluate this properly. It is47 frequently the right answer and is skipped because it is unexciting. If you48 reject it, say why in one sentence — that sentence is the justification for49 everything the new thing will cost.50- **The straightforward new build.** The obvious shape, done plainly.51- **The one that is right if a constraint changes.** Usually the one that scales52 further or costs more. Naming it makes the trade explicit rather than53 implicit.5455For each: what it costs to build, what it costs to run, what it costs to56operate, what it makes easy later, and **what it makes hard later**. That last57column is the one that predicts regret.5859## 4. Boring by default; spend novelty once6061Every unfamiliar technology has a cost that does not show up in the comparison62table: nobody knows its failure modes, its operational surprises, or how to63debug it under pressure. That cost is real and it is paid at the worst moment.6465Allow yourself one interesting choice per project, in the place where it buys66the most. Everything else is the thing the team already runs.6768A good test: for each component, who on the team could fix it if it broke on a69Friday evening? If the answer is "the person who chose it", that is the risk,70stated.7172## 5. Design the failure, not just the success7374For each option, walk the failure paths before deciding:7576- What happens when the dependency is down? Slow is worse than down — plan for77 slow.78- What happens on a partial write, a retry, a duplicate delivery?79- What is the blast radius of one bad record, one bad deploy, one bad tenant?80- How does it behave at zero, at one, and at a hundred times the expected load?81- How do you know it is broken — what emits the signal, and who sees it?82- How do you recover, and has anyone tried?8384An architecture diagram with no failure annotations is a sketch of the happy85path.8687## 6. Cost and operations are design, not an afterthought8889- **Idle cost.** Many systems spend most of their life idle. What does this cost90 doing nothing? Pay-per-use and scale-to-zero change the shape of what is91 affordable, at the price of a cold start you must then design around.92- **Cost that scales with the wrong thing.** Per-request, per-GB-scanned and93 per-connection pricing all punish a specific mistake. Know which one you are94 exposed to.95- **Who gets paged**, for what, and what they can do about it at that hour.96- **What the deploy looks like**, including the rollback.97- **What you will need to debug it** — logging, tracing and a way to answer98 "what happened to this one record?" without a database console.99100## 7. Draw the boundaries, and be honest about them101102The valuable part of a diagram is the lines, not the boxes. For each boundary:103104- What crosses it, in what format, and who owns that format?105- Is it synchronous or asynchronous, and what happens when the far side is slow?106- Is it a real boundary, or a folder pretending to be one? A "service" that107 shares a database with another service is one service with extra latency.108109Prefer few, well-defined boundaries over many convenient ones. Every boundary is110a place where versions drift, and drift is expensive — see `contract-change`.111112## 8. Write the ADR113114One file per significant decision, in the repo, numbered and dated. Short.115116```markdown117# ADR-014: Store submissions as immutable versions rather than editing in place118119**Status:** Accepted · 2026-09-21 · Supersedes ADR-009120121**Context**122Submissions reference a template that authors keep editing. Completed records123no longer match what the user saw. ~2% of records affected in the last quarter.124125**Decision**126Publishing snapshots the template into a numbered immutable version. Records127store the version id at creation and read through it for their lifetime.128129**Consequences**130+ Historical records stay readable; scores are reproducible.131+ The version diff becomes the changelog for free.132- Every typo fix creates a version; the version table grows.133- Readers must resolve through the record's version, including exports.134135**Rejected**136- Edit in place with an audit log — does not make old records renderable.137- Copy the whole template onto each record — 40x storage, no diffing.138139**What would reverse this**140If templates stop being editable after first use, versioning is unnecessary.141```142143The decision is stated as a **claim**, not a topic. "ADR-014: Versioning" tells144a future reader nothing; the sentence above tells them everything.145146**Rejected options and what would reverse it** are the two sections people skip147and the two that stop the same debate being re-run every year.148149## 9. Say what you are not building150151The architecture's non-goals are as load-bearing as the requirements' non-goals:152no multi-region, no offline, no real-time, single tenant per database, English153only. Each of these is a decision someone will otherwise assume went the other154way.155156## Checklist157158- [ ] Constraints written before options, including team and operational159- [ ] Decisions sorted into one-way and two-way doors; scrutiny spent on one-way160- [ ] Extending what exists evaluated properly and rejected in writing if rejected161- [ ] Each option carries what it makes *hard* later, not only what it makes easy162- [ ] At most one unfamiliar technology, and someone other than its champion can debug it163- [ ] Failure paths walked: dependency slow, partial write, retry, blast radius, recovery164- [ ] Idle cost, paging, deploy and rollback considered part of the design165- [ ] Boundaries real, few, and owned166- [ ] ADR written with the decision as a claim, plus rejected options and what would reverse it167- [ ] Architectural non-goals stated
Run npx skillmds@latest add chinthakat/solution-architecture in your terminal (requires Node.js), paste this page's agent-chat prompt into Claude, Cursor, or any MCP-connected agent, or download the SKILL.md file and copy it into your agent's skills directory.
Choose an architecture and record why — constraints before options, reversibility as the ranking axis, at least one option that extends what already exists, and an ADR that survives the people who wrote it. Use when a feature needs a shape rather than a file, when picking between services, stores or patterns, or when someone asks "how should we build this?" It is listed under Coding & Dev Tools on SkillMD.
This skill has not completed SkillMD's automated safety review yet. Capability flags: docs only. SkillMD never runs a skill's scripts for you; review the SKILL.md before installing.
This skill is tagged as working with Claude Code, Claude.ai, OpenAI Codex. SKILL.md is an open format, so most agents that read a skills directory can load it too.
Yes. Installing skills from SkillMD is free, and the skill stays under its author's original license.
chinthakat (@chinthakat) published this skill. Their other Agent Skills are listed on their SkillMD profile.