../

Software architecture

Prompting for application architecture: how a codebase is split into modules, layers and services, which patterns fit, how decisions are weighed, recorded and checked. Written for someone who can read code but hasn't designed a system before, or who manages people who do. The concepts themselves are in Software architecture and diagram notation in ERD & UML diagrams; distributed-systems concerns (scale, storage, failure) are in System design; the method behind every prompt here is in Prompting fundamentals.

How experts think

Architects start from the forces acting on the system, not from patterns. "Everything in software architecture is a trade-off" is the first law in Richards and Ford's Fundamentals of Software Architecture: a choice that improves one quality makes another worse, and the job is to choose which, on purpose. The questions an architect runs through before drawing anything:

QuestionWhy it mattersAsk the model
What are the drivers? Business goals, key use cases, quality attributes, constraintsarchitecture exists to satisfy these; anything that serves none is decoration"List the architecture drivers you can infer from my brief and ask about the gaps."
Which 3 qualities matter most?you can't maximize all of them; the top 3 decide the structure"Rank these quality attributes for my product and justify the top 3."
How would we measure each one?"fast" and "scalable" can't be checked; "p95 under 300 ms at 200 requests/s" can"Rewrite each quality as a scenario with a measurable response."
What are the constraints? Team size and skills, deadline, budget, existing systems, regulation, hostingconstraints remove options before preferences do"Which options do my constraints rule out?"
Who builds and runs it?Conway's law: a system's structure tends to copy the communication structure of the organization that builds it"Given 1 team of 4, which boundaries can we actually own?"
Where are the natural boundaries?split by business capability, rate of change and data ownership, not by technical layer"Propose module boundaries by business capability, each owning its data."
What is the simplest structure that meets the drivers?every extra moving part costs operations, debugging and onboarding time"What is the simplest architecture that meets these drivers? Justify each component."
Which decisions are hard to reverse?spend analysis on one-way doors (data model, service split, language, vendor), decide two-way doors fast"Classify each decision as easy or hard to reverse."
What could go wrong?risks found on paper are cheap; risks found in production are not"List the risks, likelihood, impact and the cheapest test for each."
How will we know it still holds?structure erodes one shortcut at a time"Propose fitness functions that fail CI when a rule is broken."
How will we remember why?the next team needs the reasoning, not just the result"Write an ADR for this decision."

The default most experienced architects reach for in a new product with one or two teams is a modular monolith: one deployable, split inside into modules with enforced boundaries. Services get extracted later when a module has a measured reason (independent scaling, team ownership, isolation). Treat a model that jumps straight to microservices for a small team as a sign it is pattern-matching, not reasoning.

By technical layer low cohesion, high coupling controllers/ services/ repositories/ payments code: 3 folders 8 links cross a boundary By business capability high cohesion, low coupling payments/ invoices/ reminders/ payments code: 1 module 2 links cross, through an API invoices payments reminders public API a file
Group by what changes together: a change to payments then stays inside one module.

Vocabulary

TermWhat it meansSay it like
Quality attribute (architecture characteristic, "-ility")a property the system must have beyond its features: performance, availability, security, modifiability, testability, deployability"Our top quality attributes are modifiability, data integrity and low operating cost."
ISO/IEC 25010the standard list of product quality characteristics; the 2023 edition names nine: functional suitability, performance efficiency, compatibility, interaction capability, reliability, security, maintainability, flexibility and safety, each with subcharacteristics (maintainability › modifiability, testability)"Name each quality by its ISO/IEC 25010 characteristic."
Quality attribute scenarioa testable statement of a quality: source, stimulus, environment, artifact, response, response measure"Express availability as a quality attribute scenario with a response measure."
Architecture drivera requirement that shapes the structure: a key use case, a quality attribute or a constraint"Trace each component back to the driver it serves."
Constrainta decision already made for you: language, cloud, budget, regulation, deadline"Constraints: TypeScript, one Postgres instance, EU data residency."
Modulea unit of code with one responsibility and a public interface; the rest is private"Each module exposes a public API; nothing imports its internals."
Boundarythe line between modules or services that dependencies may only cross through an interface"Where should the boundaries be, and what crosses each one?"
Couplinghow much one part depends on another; lower and narrower is better"Point out where coupling between billing and orders is too tight."
Cohesionhow closely the contents of one module belong together; things that change together should live together"Group code by business capability for high cohesion."
Layered architecturecode split into horizontal layers (UI, business logic, data access), each calling the one below"Would plain layers be enough here, or does the domain need more isolation?"
Dependency rulesource dependencies point inward, toward business logic; the core knows nothing about frameworks or databases"Check this design against the dependency rule."
Dependency inversionthe core defines an interface; infrastructure implements it, so the core doesn't depend on infrastructure"Invert the dependency on the payment provider."
Hexagonal architecture (ports and adapters)the core defines ports (interfaces); adapters connect them to HTTP, databases, queues, tests"Structure the order module as ports and adapters with an in-memory adapter for tests."
Clean / onion architectureconcentric layers (entities, use cases, adapters, frameworks) with the dependency rule enforced"Is clean architecture worth the ceremony for a CRUD app this size?"
Monolithone deployable unit containing the whole application"Keep it a monolith until a module has a measured reason to split."
Modular monolitha monolith split internally into modules with enforced boundaries and owned data"Design this as a modular monolith with 4–6 modules."
Microservicesindependently deployable services, each owning its data, talking over the network"What would microservices buy us, and what would they cost a 4-person team?"
Distributed monolithservices that must be deployed or changed together; the costs of both styles, the benefits of neither"Would this split produce a distributed monolith?"
Event-driven architecturecomponents react to events published through a broker instead of calling each other"Which interactions should be events instead of direct calls?"
Domain eventa record that something happened in the business, named in the past tense (OrderPlaced)"List the domain events in the checkout flow."
CQRS (command query responsibility segregation)separate models for writes (commands) and reads (queries)"Is CQRS justified here, or do reads and writes have the same shape?"
Event sourcingstoring state as the full sequence of events and rebuilding it by replaying them"Only suggest event sourcing if we need full audit history; say what it costs."
Domain-driven design (DDD)modeling software on the business domain, in the domain's own language"Use DDD vocabulary: bounded contexts, aggregates, domain events."
Bounded contexta boundary inside which one model and its terms are consistent; "Order" in sales is not "Order" in shipping"Identify the bounded contexts and draw a context map."
Ubiquitous languagethe shared vocabulary of domain experts and code"Build a glossary of our ubiquitous language from these notes."
Aggregatea cluster of objects changed together as one unit, with rules (invariants) it protects"What are the aggregates, and what invariant does each protect?"
Anti-corruption layera translation layer that keeps a foreign or legacy model out of your own"Put an anti-corruption layer in front of the legacy ERP."
Context mapa diagram of bounded contexts and how they relate (customer/supplier, shared kernel, anti-corruption layer)"Draw a context map for these 5 contexts."
ADR (architecture decision record)a short numbered document recording one decision: context, decision, consequences"Write ADR-0004 for choosing Postgres over MongoDB."
C4 modelfour zoom levels of diagram: system context, containers, components, code"Give me C4 level 1 and level 2 diagrams in Mermaid."
Fitness functionan automated check that an architectural rule or quality still holds, run in CI"Write fitness functions that fail the build if domain code imports infrastructure."
ATAM (Architecture Tradeoff Analysis Method)the Software Engineering Institute's method for evaluating an architecture against quality-attribute goals"Run an ATAM-style evaluation of this design."
Sensitivity point / trade-off pointa decision that strongly affects one quality / a decision that affects several qualities in opposite directions"Mark the sensitivity points and trade-off points."
Strangler figreplacing a legacy system piece by piece behind a facade until the old one can be switched off"Plan a strangler-fig migration, one capability at a time."
Technical debtthe future cost of shortcuts taken now"Rank the technical debt by cost of delay."
Blast radiushow much breaks when one part fails or changes"What is the blast radius of a bad deploy of the billing module?"
Trust boundarya line where data passes between parts with different privileges; where security checks belong"Mark the trust boundaries and threat-model them with STRIDE."

Plain layers and ports and adapters differ in which way the source-code dependencies point:

Layered dependencies point down UI controllers, pages business logic the core data access repositories, ORM Postgres the core imports storage Ports and adapters (hexagonal) dependencies point in domain + use cases knows no adapter PlaceOrder OrderRepo PaymentGateway REST API adapter tests adapter Postgres adapter Stripe adapter tests swap in an in-memory OrderRepo calls the core implements a port port
In both, a request still flows from the UI to the database; what changes is who depends on whom.

Trade-off analysis

Ask for trade-offs in a fixed shape so they can be compared and argued with. Two shapes do most of the work.

A quality attribute scenario (the six-part form from the Software Engineering Institute's architecture books) makes a quality testable:

PartExample
Sourcea developer on the team
Stimulusadds a new payment provider
Environmentat design time, normal sprint
Artifactthe payments module
Responsechange is confined to one new adapter; no other module changes
Response measuredone in under 3 days, zero changes outside payments/

An ATAM-style trade-off table compares options against the scenarios and names what each decision touches:

DecisionScenario affectedSensitivity pointTrade-off pointRiskNon-risk
async event between orders and invoicinginvoice created within 5 s of orderbroker delivery latencydecoupling vs harder debugging and eventual consistencyduplicate events create duplicate invoicesidempotency key on invoice creation
one Postgres for all moduleszero lost paymentstransaction scopeintegrity and simplicity vs modules sharing a failure domainone module's slow queries starve othersschemas per module keep ownership clear

A risk is a decision that may cause a quality goal to be missed; a non-risk is a decision judged safe, with the reason. Asking for both stops the model from listing only problems or only praise.

Diagrams and ADRs

Ask for diagrams as text (Mermaid, PlantUML, Structurizr DSL or D2) so you can render, diff and edit them; ask for one C4 level per diagram. What a correct Mermaid C4 container diagram looks like:

C4Container
  title Containers: invoicing app
  Person(user, "Freelancer")
  System_Ext(stripe, "Stripe", "Card payments")
  System_Boundary(app, "Invoicing app") {
    Container(web, "Web app", "Next.js", "UI")
    Container(api, "API", "Bun", "Use cases")
    ContainerDb(db, "Database", "PostgreSQL")
  }
  Rel(user, web, "Uses", "HTTPS")
  Rel(web, api, "Calls", "JSON/HTTPS")
  Rel(api, db, "Reads and writes", "SQL")
  Rel(api, stripe, "Charges cards", "HTTPS")
CheckWhy
Title and scope on every diagramreaders assume a diagram shows everything
One C4 level per diagrammixing containers and classes makes every box ambiguous
Every arrow labeled with intent and protocolan unlabeled line says only "related"
Technology on each container"API" alone hides the decisions
Render it before trusting itgenerated Mermaid often has syntax errors, and Mermaid's C4 support lacks some features of C4-PlantUML and Structurizr

Each C4 level zooms into one box of the level above:

1 Context people, systems 2 Containers apps, data stores 3 Components parts of one app 4 Code classes (optional) Invoicing app our system Freelancer person Stripe card payments Postmark email creates invoices charges emails Invoicing app Web app Next.js API Bun Database PostgreSQL HTTPS JSON SQL HTTPS HTTPS API Web app container Invoicing Payments Reminders Tax export Database container JSON charge HTTPS HTTPS SQL Payments component PaymentService «interface» PaymentGateway «interface» PaymentRepository StripeAdapter PgPaymentRepo uses uses implements implements usually generated from code by an IDE, if drawn at all

1/4

Level 1, system context: your system as one box, the people who use it and the external systems it depends on. Anyone in the company can read it.

ADR formats: Nygard (title, status, context, decision, consequences: the original 2011 format) and MADR (Markdown Architectural Decision Records: adds decision drivers, considered options, the pros and cons of each and how the decision will be confirmed). One decision per ADR; accepted ADRs are not edited, a new ADR supersedes them. A full example is in Software architecture.

Proposed Accepted Superseded by ADR-N Rejected Deprecated agreed replaced turned down no longer applies Nygard's statuses: proposed, accepted, deprecated, superseded; MADR adds rejected ADR-0004 One Postgres for all Status: Superseded by ADR-0009 Context Decision Consequences body never edited ADR-0009 Own DB for reports Status: Accepted Context Decision Consequences Supersedes ADR-0004 links both ways
Only the old record's status line changes; the reasoning stays as it was written.

Brief the model

Each input has a slot in the skeleton; the last column says which.

InputWhy it mattersExampleSlot
Product and domainboundaries come from the business, not the tech"B2B invoicing for freelancers: clients, invoices, payments, reminders, tax reports."<context>
Top use casesthe flows the structure must make easy"1. Create and send an invoice. 2. Client pays by card. 3. Overdue reminders. 4. Quarterly tax export."<context>
Ranked quality attributes, with numbersdecides between otherwise equal options"1. Correctness of money (zero lost payments). 2. Modifiability (ship weekly). 3. Ops cost under $300/month."<requirements>
Constraintsremoves options before preferences do"TypeScript on Bun, Postgres, one cloud region in the EU, GDPR."<requirements>
TeamConway's law and operational capacity"3 developers, no dedicated ops, one on-call rotation."<context>
Scale and growthprevents both over- and under-building"≈ 2,000 customers in year 1, ≈ 20,000 in year 3; 50 requests/s peak."<context>
Current statea redesign starts from what existspaste the folder tree, dependency graph, pain points, incident notes<materials>
Integrationsexternal systems shape boundaries and failure modes"Stripe for payments, Postmark for email, an accounting export to Xero."<context>
Decisions already madestops the model reopening thempaste existing ADRs; "non-negotiable: Postgres"<materials>, <requirements>
Time horizonprototype, MVP or 5-year platform need different rigor"MVP in 3 months; expected to live 5+ years."<context>
Deliverable and readerthe format and depth depend on who reads it"ADR plus C4 diagrams for the 2 other developers and a non-technical cofounder."<task> (the deliverable), <context> (the reader)

What to ask for

StageDeliverableAsk for it like
Discoverarchitecture drivers list"Extract the drivers: use cases, quality attributes, constraints."
quality attribute scenarios"Write 2 scenarios per top quality attribute, each with a response measure."
utility tree"Build an ATAM utility tree: qualities → refinements → scenarios, each rated H/M/L for importance and difficulty."
domain glossary"Draft a ubiquitous-language glossary from these interview notes."
event storming outline"List the domain events of the business on a timeline, with the commands and actors that trigger them."
Shapecontext map"Identify bounded contexts and the relationship between each pair."
module decomposition"A table of modules: responsibility, data owned, public API, depends on."
candidate architectures"3 candidate architectures, each in one paragraph and one diagram."
C4 diagrams"C4 system context and container diagrams as Mermaid."
dependency rules"An allowed-imports matrix between layers and modules."
Decidetrade-off table"Score each candidate against the top 3 quality attributes, with reasons."
ADR"An ADR in Nygard format: title, status, context, decision, consequences."
risk register"Risks: description, likelihood, impact, mitigation, owner, trigger."
spike plan"The smallest prototype that would retire the riskiest assumption."
Buildfolder and package layout"The folder tree for the modular monolith, one line per folder."
interfaces and ports"The port interfaces for the payments module, in TypeScript."
walking skeleton"A thin end-to-end slice through every container, to deploy first."
fitness functions"dependency-cruiser rules and an architecture test for these boundaries."
Evolvearchitecture review"Review this pull request against our ADRs and dependency rules."
coupling hotspots"From this dependency graph, find cycles and the most depended-on modules."
migration plan"A strangler-fig plan with phases, rollback points and the test that ends each phase."
architecture document"Fill the arc42 template sections we need for a 2-page overview."

The prompt chain

The chain's deliverable is an architecture proposal: the drivers, the chosen architecture and what it trades away, ADRs for the hard-to-reverse decisions and C4 diagrams the team can build from. Run the four stages in order; each prompt uses the skeleton and replaces "act as an architect" with the standards an architect would apply (ISO/IEC 25010 qualities, C4, MADR, ATAM).

1. Interview

Use first, before anything is drawn: the drivers decide the architecture, and you may not know which ones matter.

<context>
I'm [your role, e.g. the technical cofounder] at
[organization, e.g. a 3-person B2B SaaS startup]. We are
building [system, e.g. invoicing for freelancers:
clients, invoices, card payments, reminders, tax export].
Where it stands:
[stage: greenfield | prototype | in production].
I'm not an architect. The proposal will be read by
[readers, e.g. 2 developers and a non-technical cofounder].
</context>
 
<task>
Interview me before designing anything. The end
result will be an architecture proposal (candidate
architectures, a recommendation recorded as ADRs, C4
diagrams); first you need its architecture drivers.
</task>
 
<requirements>
- At most 10 questions, grouped under: business goals and
  key use cases; quality attributes (use the ISO/IEC 25010
  characteristics); constraints; team and operations; scale
  and growth; existing systems and decisions already made.
- For each question: one line on how the answer changes the
  architecture, and 2–3 typical answers I can pick from.
- No architecture, patterns or technologies yet.
</requirements>
 
<quality_bar>
Before answering, check your questions against:
- Each answer could change a structural
  decision; drop any question that couldn't.
- Quality questions ask for a number (a
  response measure), not an adjective.
- Nothing I already told you is asked again.
</quality_bar>
 
<output_format>
Numbered questions under the
group headings, and nothing else.
</output_format>
 
<process>
Ask all the questions in one message, then stop. When I
answer, restate the drivers as three lists (use cases;
ranked quality attributes as scenarios with response
measures; constraints), mark anything still open [NEEDS
SOURCE], and end with a list of the assumptions you made.
</process>

2. Options

Use once the drivers are agreed: left alone, the model picks one familiar pattern; you want to see the real choice.

<materials>
[paste the drivers from stage 1, with my answers]
</materials>
 
<context>
Team: [team, e.g. 3 developers, no dedicated
ops, one on-call rotation]. Time horizon:
[horizon: prototype | MVP | 5+ year platform].
</context>
 
<task>
Candidate architectures for this system, so I can
choose one before anything is drawn or written up.
</task>
 
<requirements>
- 2–4 materially different candidates; one must
  be the simplest workable option (a modular
  monolith or plain layers). Candidates that
  differ only in technology names don't count.
- For each: one paragraph, the modules or services, how it
  meets each top quality attribute, the operating load for
  this team, and which decisions would be hard to reverse.
- Use ATAM vocabulary: sensitivity points,
  trade-off points, risks and non-risks.
- Never invent numbers, names, quotes or sources:
  write [NEEDS SOURCE] where support is missing.
</requirements>
 
<quality_bar>
Before answering, check your draft against:
- Every component serves a numbered driver.
- Each candidate names what it makes
  worse, not only what it improves.
- The trade-off table scores every
  candidate on every top quality attribute.
- The recommendation names the assumption
  that, if wrong, would flip it.
</quality_bar>
 
<output_format>
One section per candidate; a trade-off table
(candidate | each top quality attribute, scored +, 0
or - with a reason | operating load | hard-to-reverse
decisions); a recommendation in under 100 words.
</output_format>
 
<process>
End with a list of the assumptions you made. Then stop and
wait for my choice: no ADRs, diagrams or module tables yet.
</process>

3. Produce

Use after you have chosen: the full proposal for one candidate, in the form the team will review.

<materials>
[paste the agreed drivers from stage 1]
[paste the chosen candidate and
the trade-off table from stage 2]
[paste existing ADRs, the folder tree
or the integration list, if any]
</materials>
 
<context>
[product and team, e.g. B2B invoicing for freelancers,
built by 3 developers with no ops]. The readers: [readers,
e.g. the other 2 developers and a non-technical cofounder].
We chose [candidate, e.g. candidate 1, the
modular monolith] because [reason, e.g. the
lowest operating load for a team with no ops].
</context>
 
<task>
The architecture proposal for the chosen candidate:
the document the team approves and then builds from.
</task>
 
<requirements>
- Name qualities with their ISO/IEC 25010
  characteristics; write the top 3 as quality
  attribute scenarios with response measures.
- C4 model: a system context and a
  container diagram, one level each, in
  [notation: Mermaid | PlantUML | Structurizr DSL | D2];
  every arrow labeled with intent and
  protocol; technology on every container.
- Each hard-to-reverse decision as an ADR in
  [ADR format: MADR | Nygard], status Proposed,
  with at least 2 negative consequences.
- Modules by business capability; each owns
  its data and exposes a public API;
  dependencies point inward, with no cycles.
- Risks and non-risks in ATAM
  style, each tied to a decision.
- Never invent numbers, names, quotes or sources:
  write [NEEDS SOURCE] where support is missing.
</requirements>
 
<quality_bar>
Before answering, check your draft against:
- Every component and ADR traces to a numbered driver.
- The diagrams, the module table and the
  prose name the same parts, with no extras.
- No module reads or writes another module's tables.
- The operating load fits the team in <context>.
- Each fitness function would fail
  CI when its rule is broken.
</quality_bar>
 
<output_format>
Markdown, under [length, e.g. 4 pages], in these
sections: summary (5 lines); drivers; architecture
overview; C4 diagrams; module table (module |
responsibility | data owned | public API | depends on);
ADRs; quality scenarios and how the design meets each;
risks and non-risks; fitness functions; open questions.
</output_format>
 
<process>
Ask me up to 3 questions first if anything
missing would change your answer; otherwise go
on. End with a list of the assumptions you made.
</process>

4. Review

Run this in a fresh chat, pasting only the proposal and the drivers. A model reviewing its own draft shares its blind spots, so the critique has to come from a chat that didn't write it; for a system that handles money or personal data, have a person review it too.

<materials>
<proposal>
[paste the architecture proposal]
</proposal>
<drivers>
[paste the agreed drivers]
</drivers>
</materials>
 
<context>
This is a fresh chat: you did not write this proposal.
It goes to [reviewers, e.g. the two developers who
will build it] for approval [when, e.g. on Friday].
</context>
 
<task>
An ATAM-style review of the proposal before it is
approved: what would make it miss its quality goals.
</task>
 
<requirements>
- A short utility tree: quality attributes, then scenarios,
  each rated H/M/L for importance and difficulty.
- For the 5 highest-rated scenarios: how the
  design responds, with its sensitivity points,
  trade-off points, risks and non-risks.
- Score the proposal 1–5 on: traceability,
  measurable qualities, trade-offs, alternatives,
  boundaries, dependencies, fit to team,
  reversibility, risks, diagrams, enforcement.
- Do not rewrite the proposal and do not praise it.
- Never invent numbers, names, quotes or sources:
  write [NEEDS SOURCE] where support is missing.
</requirements>
 
<quality_bar>
Before answering, check your review against:
- Every problem cites the section,
  diagram or ADR it comes from.
- Problems are ranked by the business
  goal they threaten, worst first.
- You compared the diagrams with the module
  table, and the ADRs with the drivers.
- If you found fewer than 5 problems,
  you say which checks came back clean.
</quality_bar>
 
<output_format>
The utility tree; a scenario table (scenario | design
response | sensitivity points | trade-off points |
risks | non-risks); the scorecard; the ranked fixes
(problem | evidence | fix | effort S, M or L).
</output_format>
 
<process>
End with a list of the assumptions you made.
</process>

Take the top fixes back to the chat that wrote the proposal: "Apply fixes 1–3, keep everything else, list what you changed." Then rerun stage 4 in another fresh chat if the changes were structural.

Goals and loops

In an agent that runs commands and checks its own work, such as Claude Code, the Produce stage can run until it measurably passes: /goal keeps starting turns until a condition holds, and /loop repeats a prompt or skill on an interval. The checker reads only the conversation, so every condition below names a check whose output Claude prints, the constraints that must survive, and a bound. How to write your own: Goals and loops.

TaskCompletion condition
Write the ADRs for the proposal/goal every ADR in docs/adr/ has Status, Context, Decision and Consequences, npx markdownlint-cli2 "docs/adr/*.md" reports 0 errors (show its last line), and each ADR names the quality-attribute scenario it serves; or stop after 15 turns
Enforce the module boundaries/goal the architecture test (npx depcruise src --config .dependency-cruiser.cjs) reports 0 violations, shown by its summary line; no rule removed or weakened; or stop after 20 turns
Draw the C4 diagrams/goal npx -p @mermaid-js/mermaid-cli mmdc -i docs/c4.md -o docs/c4.svg renders without errors, and every container in the module table appears in the diagram (list any missing: none); or stop after 10 turns

Loops that fit: during a migration, /loop 30m to rerun the fitness functions on the branch and report new violations only. For a daily check on main use /schedule: loops stop when Claude Code closes and expire after seven days.

What a checker can't judge: whether the trade-offs suit your business, team and timeline. That stays with the Review stage in a fresh chat and an experienced architect.

Prompt library

One entry per deliverable from What to ask for, outside the chain. Quick is the minimum that still works; Full is the skeleton filled in. Replace each placeholder: pick one option, or write your own value.

Quality attribute scenarios

Stage: produce · Use when: the brief says "fast", "scalable" or "secure" and you need something testable.

Quick

Turn these requirements into quality attribute scenarios
(source, stimulus, environment, artifact, response, response
measure), named by ISO/IEC 25010 characteristic: [paste
requirements]. Check that every response measure is a number
a test could check, and mark each number as mine to confirm.

Full

<materials>
[paste the requirements, user stories or meeting notes]
</materials>
 
<context>
[system, e.g. B2B invoicing for freelancers], built by
[team, e.g. 3 developers]. Expected load: [scale, e.g.
2,000 customers in year 1, 50 requests/s at peak].
</context>
 
<task>
Quality attribute scenarios for the
qualities these requirements imply, so we
can rank them and design against the top 3.
</task>
 
<requirements>
- The six-part form: source, stimulus, environment,
  artifact, response, response measure.
- Name each quality by its ISO/IEC 25010 characteristic and
  subcharacteristic, e.g. maintainability › modifiability.
- 2 scenarios for each of the top 5 qualities: one
  in normal operation, one under stress or failure.
- Mark every number you propose
  "(proposed)", for me to confirm.
- Never invent numbers, names, quotes or sources:
  write [NEEDS SOURCE] where support is missing.
</requirements>
 
<quality_bar>
Before answering, check your draft against:
- Every response measure is a number with a
  unit that a test or a dashboard could check.
- No scenario restates a feature; each describes a quality.
- The ranking follows my requirements, not a generic order.
</quality_bar>
 
<output_format>
A table: quality (ISO/IEC 25010) | source | stimulus |
environment | artifact | response | response measure.
Then the top 3, ranked, one line each on why.
</output_format>
 
<process>
Ask me up to 3 questions first if anything
missing would change your answer; otherwise go
on. End with a list of the assumptions you made.
</process>

Architecture decision record

Stage: produce · Use when: a decision has been made and needs writing down before people forget why.

Quick

Write ADR-[number, e.g. 0004] in [ADR format: MADR | Nygard]
for: [decision, e.g. one Postgres with a schema per module].
Include 2+ negative consequences and a "revisit if" line.
Check each rejected option has a real reason; mark missing
facts [NEEDS SOURCE].

Full

<materials>
[paste the discussion notes, the
trade-off table and any related ADRs]
</materials>
 
<context>
Our ADRs live in [location, e.g. docs/adr/ in
the repo] and are read by [readers, e.g. the
current developers and whoever joins next year].
</context>
 
<task>
ADR-[number, e.g. 0004] recording this decision: [decision,
e.g. one PostgreSQL database with a schema per module].
</task>
 
<requirements>
- Template: [ADR format: MADR | Nygard]. MADR
  sections: decision drivers, considered options,
  pros and cons of each, confirmation. Nygard
  sections: context, decision, consequences.
- Status: [status: Proposed | Accepted]. If it replaces
  an earlier ADR, say which one it supersedes.
- At least 2 positive and 2 negative consequences, and a
  "revisit if" line naming a condition we could observe.
- One decision only; under one page.
- Never invent numbers, names, quotes or sources:
  write [NEEDS SOURCE] where support is missing.
</requirements>
 
<quality_bar>
Before answering, check your draft against:
- The context states the forces, not the conclusion.
- Each rejected option has a real reason, not a straw man.
- The negative consequences are the ones
  a skeptic on the team would raise.
- Someone joining next year could tell from
  it whether the decision still holds.
</quality_bar>
 
<output_format>
Markdown in the chosen template, titled with
the number and the decision in under 10 words.
</output_format>
 
<process>
End with a list of the assumptions you made.
</process>

C4 diagrams

Stage: produce · Use when: you need context and container views to paste into a README and keep in the repo.

Quick

From this description, draw C4 system context and
container diagrams in Mermaid (C4Context, C4Container):
[paste description]. Label every Rel with intent and
protocol, put technology on every container, and check
nothing appears that the description doesn't mention;
list what you couldn't place.

Full

<materials>
[paste the architecture description,
module table or proposal]
</materials>
 
<context>
The diagrams go in [where, e.g. the repo README
and the onboarding doc], read by [readers, e.g.
new developers and a non-technical cofounder].
</context>
 
<task>
C4 diagrams of this system, as
text we can render, diff and edit.
</task>
 
<requirements>
- Levels:
  [C4 levels: system context | container | component],
  one level per diagram.
- Notation:
  [notation: Mermaid | PlantUML | Structurizr DSL | D2].
- A title and scope on every diagram; every
  arrow labeled with intent and protocol;
  technology on every container and data store.
- Draw only elements the description mentions.
- Never invent numbers, names, quotes or sources:
  write [NEEDS SOURCE] where support is missing.
</requirements>
 
<quality_bar>
Before answering, check your draft against:
- Every element and arrow is in the description,
  and everything in the description is placed.
- No diagram mixes C4 levels.
- The syntax uses only features the notation has
  (Mermaid's C4 support is narrower than C4-PlantUML's).
</quality_bar>
 
<output_format>
One fenced code block per diagram; then anything you could
not place; then a 3-line legend for non-technical readers.
</output_format>
 
<process>
End with a list of the assumptions you made.
</process>

Module boundaries for an existing codebase

Stage: produce · Use when: a codebase has grown without a plan, changes ripple, and you need modules.

Quick

Here are our folder tree and module dependency graph:
[paste tree and graph]. Infer the business capabilities,
propose target modules (responsibility, data owned,
public API), list the cycles, and give an incremental
plan. Check every step leaves the app shippable.

Full

<materials>
<tree>
[paste the folder tree]
</tree>
<graph>
[paste the dependency graph, e.g.
from dependency-cruiser or madge]
</graph>
</materials>
 
<context>
Pain points: [pain points, e.g. slow builds,
every change touches 5 folders, brittle tests].
Team: [team, e.g. 4 developers, weekly releases].
</context>
 
<task>
A target module decomposition for this
codebase and an incremental plan to reach it.
</task>
 
<requirements>
- Modules by business capability, not technical
  layer; each owns its data and exposes a public API.
- List the dependency cycles and
  the 10 most depended-on files.
- Steps that each leave the app shippable, using
  [method: branch by abstraction | strangler fig].
- One fitness function per step that
  fails CI if the step regresses.
- Never invent numbers, names, quotes or sources:
  write [NEEDS SOURCE] where support is missing.
</requirements>
 
<quality_bar>
Before answering, check your draft against:
- Every file in the tree lands in exactly one module.
- Every cross-module call in the
  target goes through a public API.
- No step needs a code freeze or a big-bang merge.
</quality_bar>
 
<output_format>
The capabilities; a module table (module |
responsibility | data owned | public API | depends
on); cycles and hotspots; the step plan (step |
what moves | fitness function | rollback).
</output_format>
 
<process>
Ask me up to 3 questions first if anything
missing would change your answer; otherwise go
on. End with a list of the assumptions you made.
</process>

Risk register

Stage: produce · Use when: a design is about to be approved and nobody has listed what could go wrong.

Quick

For this design: [paste design], write a risk
register (risk | cause | likelihood L/M/H | impact
L/M/H | mitigation | cheapest early test |
trigger), 8–12 rows, worst first. Check every risk
names a component or decision: no generic risks.

Full

<materials>
[paste the design document, diagrams and ADRs]
</materials>
 
<context>
Approval is [when, e.g. next week]. Before then
we can spend [budget, e.g. 3 developer-days] on
spikes to test the worst risks.
</context>
 
<task>
A risk register for this design, to choose
which risks to test before approval.
</task>
 
<requirements>
- 8–12 risks, each naming the
  component or decision it comes from.
- Cover technical, operational, security (trust boundaries,
  STRIDE) and organizational risks (Conway's law, skills).
- For each, the cheapest early test: a
  spike or prototype that fits the budget.
- Rate likelihood and impact on [scale: L/M/H | 1–5].
- Never invent numbers, names, quotes or sources:
  write [NEEDS SOURCE] where support is missing.
</requirements>
 
<quality_bar>
Before answering, check your draft against:
- No risk could be pasted into another
  project's register unchanged.
- Each trigger is observable: a metric, an event or a date.
- The top 3 risks threaten the
  top-ranked quality attributes.
</quality_bar>
 
<output_format>
A table: ID | risk | cause | likelihood |
impact | mitigation | cheapest early test
| owner role | trigger. Worst first.
</output_format>
 
<process>
End with a list of the assumptions you made.
</process>

Fitness functions

Stage: produce · Use when: the rules exist in a document and you want CI to enforce them.

Quick

Our architecture rules: [paste rules]. Stack: [stack,
e.g. TypeScript, Bun, Vitest]. For each rule write an
automated check, what it catches and misses, and how to
run it in CI. Check every option exists in the tool's
current docs; mark any you're unsure of [CHECK DOCS].

Full

<materials>
[paste the dependency rules or
allowed-imports matrix, and the folder tree]
</materials>
 
<context>
Stack: [stack, e.g. TypeScript on Bun, Vitest, GitHub
Actions]. Today the rules live only in a document and
get broken about [frequency, e.g. once a sprint].
</context>
 
<task>
Fitness functions that fail CI when
an architecture rule is broken.
</task>
 
<requirements>
- One check per rule, using
  [tool: dependency-cruiser | ESLint | architecture test].
- Cover import direction, cycles, imports
  of another module's internals, and
  domain code importing infrastructure.
- For each: what it catches, what it misses,
  and roughly how long it adds to CI.
- Only options that exist in the tool's current
  docs; mark any you are unsure of [CHECK DOCS].
- Never invent numbers, names, quotes or sources:
  write [NEEDS SOURCE] where support is missing.
</requirements>
 
<quality_bar>
Before answering, check your draft against:
- Each check fails on a deliberately broken
  import; give that import as its test case.
- No check relies on file names when
  it could check the import graph.
- The config is complete enough to paste and run.
</quality_bar>
 
<output_format>
One code block per check, each followed by: rule |
catches | misses | CI cost. Then the CI job snippet.
</output_format>
 
<process>
End with a list of the assumptions you made.
</process>

Migration plan

Stage: produce · Use when: a legacy system or module needs replacing without a big-bang rewrite.

Quick

Current system: [paste summary, tree, pain points].
Target: [paste target design]. Write a strangler-fig
plan: phases, what moves, the facade that switches
traffic, data migration by expand/contract, rollback per
phase. Check every phase leaves the system shippable.

Full

<materials>
<current>
[paste the current system's summary, folder
tree, pain points and incident notes]
</current>
<target>
[paste the target architecture or proposal]
</target>
</materials>
 
<context>
Team: [team, e.g. 3 developers who also handle
support]. Fixed dates: [constraints, e.g. no
deploys in the last week of each quarter].
</context>
 
<task>
A migration plan from the current system
to the target, one capability at a time.
</task>
 
<requirements>
- Pattern: [pattern: strangler fig | parallel run],
  with the facade or routing that switches traffic.
- Data moves by expand and contract: no step needs downtime,
  and no one-way schema change runs without a backup.
- Each phase: what moves, how traffic switches, the
  rollback, and the test that proves it is done.
- Phase 1 is the lowest-risk capability
  that still teaches us something.
- Never invent numbers, names, quotes or sources:
  write [NEEDS SOURCE] where support is missing.
</requirements>
 
<quality_bar>
Before answering, check your draft against:
- Every phase leaves the system
  shippable and can be rolled back.
- No phase moves code and data in
  one step without a fallback.
- The plan ends with the old system switched
  off, not running forever beside the new one.
</quality_bar>
 
<output_format>
A phase table (phase | capability | what
moves | traffic switch | data step | rollback
| done when), then the risks of each phase.
</output_format>
 
<process>
Ask me up to 3 questions first if anything
missing would change your answer; otherwise go
on. End with a list of the assumptions you made.
</process>

Code review against the architecture

Stage: review · Use when: a pull request may be eroding the boundaries.

Quick

Rules: [paste dependency rules]. ADRs: [paste relevant
ADRs]. Diff: [paste diff]. List each violation (file,
line, rule or ADR broken, why it matters, smallest fix),
worst first, no style comments. Check you cite a rule
for every finding; if none, say which rules you checked.

Full

<materials>
<rules>
[paste the dependency rules or allowed-imports matrix]
</rules>
<adrs>
[paste the relevant ADRs]
</adrs>
<tree>
[paste the folder tree]
</tree>
<diff>
[paste the diff or the changed files]
</diff>
</materials>
 
<context>
The change: [change, e.g. late-payment fees on
invoices], by [author, e.g. a developer new to the
codebase]. It is due to merge [when, e.g. today].
</context>
 
<task>
An architecture review of this
change: violations and risks only.
</task>
 
<requirements>
- Check import direction, module boundaries,
  data ownership and the decision in each ADR.
- Severity per finding: blocker (must
  fix before merge), major or minor.
- No style or naming comments; do not rewrite the code.
- Never invent numbers, names, quotes or sources:
  write [NEEDS SOURCE] where support is missing.
</requirements>
 
<quality_bar>
Before answering, check your review against:
- Every finding cites a file and line
  and the rule or ADR it breaks.
- Each fix is the smallest change that restores the rule.
- If you found nothing, you list the rules you checked.
</quality_bar>
 
<output_format>
A table: severity | file:line | rule or ADR |
why it matters | smallest fix. Then any rule
the code suggests we should change instead.
</output_format>
 
<process>
End with a list of the assumptions you made.
</process>

Worked example

Weak prompt

Design a microservices architecture
for my SaaS app. Use best practices.

What's wrong

  • It presupposes the answer (microservices) before a single driver is known.
  • No product, team, scale, constraints or ranked qualities, so there is nothing to trade against.
  • "Best practices" invites the most generic answer available: an API gateway, a service per noun, Kubernetes, Kafka and a service mesh. That is an architecture for hundreds of engineers, handed to a team of three.
  • No deliverable: you get prose, not an ADR, diagrams and a module table you could review.

Strong prompt

<context>
Product: B2B invoicing for freelancers:
clients, invoices, card payments via Stripe,
overdue reminders, quarterly tax export.
Team: 3 developers, one on-call rotation, no dedicated ops.
Scale: about 2,000 customers in year 1 and
20,000 in year 3; 50 requests/s at peak.
Readers: the other 2 developers
and a non-technical cofounder.
</context>
 
<task>
An architecture proposal I can take to the team: two
candidate architectures, a recommendation recorded
as an ADR, and the views we need to start building.
</task>
 
<requirements>
- Ranked quality attributes (ISO/IEC 25010 names): 1.
  functional correctness of payments: no lost or double
  charges; 2. maintainability: one developer ships a
  feature a week; 3. operating cost under $300/month.
- Constraints: TypeScript on Bun,
  PostgreSQL, EU hosting, GDPR.
- Candidates: a modular monolith, and the
  smallest service split you could defend.
- C4 context and container diagrams in
  Mermaid; the ADR in Nygard format.
- Justify every component against a numbered attribute.
- Never invent numbers, names, quotes or sources:
  write [NEEDS SOURCE] where support is missing.
</requirements>
 
<quality_bar>
Before answering, check your draft against:
- Every component traces to attribute 1, 2 or 3.
- The trade-offs say what each candidate makes worse.
- Each module owns its data: no module
  reads another module's tables.
- The operating load fits 3 developers with no ops.
</quality_bar>
 
<output_format>
1. Trade-off table: candidate |
   attribute 1 | 2 | 3 | operating load.
2. The recommendation as ADR-0001.
3. The two C4 diagrams.
4. Module table: module | responsibility
   | data owned | public API.
5. The top 5 risks with mitigations,
   and 3 fitness functions.
</output_format>
 
<process>
Ask me up to 3 questions first if anything
missing would change your answer; otherwise go
on. End with a list of the assumptions you made.
</process>

What came back

An illustrative, abridged response:

No questions: the brief covers the decision. Assumptions
are at the end.
 
1. Trade-offs
Candidate        | 1 Correct | 2 Maint. | 3 Cost | Ops load
Modular monolith | + one tx  | +        | +      | low
3 services       | - sagas   | 0        | -      | high
 
2. ADR-0001: Build a modular monolith
Status: Proposed
Context: 3 developers, no ops; payment correctness is the
top attribute. One PostgreSQL database keeps a payment and
its invoice update in one transaction.
Decision: one deployable, 4 modules, a schema per module.
Consequences: + one deploy, atomic money updates, under
$300/month. - One failure domain: a slow query in one
module can starve the others. - Boundaries hold only if CI
enforces them.
 
3. C4 context and container diagrams (Mermaid, omitted)
 
4. Modules
Module     | Responsibility | Data owned | Public API
invoicing  | create, send   | invoices   | createInvoice
payments   | charge, refund | payments   | charge, refund
reminders  | overdue nudges | schedules  | scheduleFor
tax-export | quarterly CSV  | exports    | runExport
Reminders runs a nightly job that selects overdue rows by
invoices.due_date and queues the emails.
 
5. Risks (2 of 5)
- Stripe can deliver a webhook twice: store an idempotency
  key per payment event.
- One module's slow query starves the rest: a statement
  timeout on each module's database role.
Fitness functions: no import of another module's internal
folders; no cycles between modules; domain code imports no
infrastructure package.
 
Assumptions:
1. Tax export runs as a quarterly batch job.
2. Reminders go out by email only.
3. Stripe reports payment results by webhook.

How an expert judged it

Checked against the prompt's own quality bar:

  • Every component traces to an attribute: passes. The single database is justified by attribute 1 (a payment and its invoice in one transaction), the single deployable by attribute 3 and the team size.
  • Says what each candidate makes worse: passes, though in the ADR rather than the table: one failure domain, and boundaries that hold only if CI enforces them.
  • Fits the team: passes. One deployable, no broker, no cluster to run.
  • Each module owns its data: fails. Reminders selects from invoices.due_date in the invoicing schema: the shared-table coupling the bar ruled out, in a response that says it checked. A change to the invoices table can now break reminders silently, and none of the three fitness functions would notice, because they check imports and this dependency is a SQL query.
  • Assumptions: worth reading. "Reminders go out by email only" is a product decision for the cofounder, not the model's to make.

Verdict: one structural fix before the team sees it; the rest is ready for the stage 4 review.

The follow-up

In the module table, reminders reads invoices.due_date
directly, which breaks "each module owns its data". Fix
it one of two ways: invoicing adds a query to its public
API (for example listOverdue(asOf)), or it publishes an
InvoiceDue event that reminders stores in its own
schema. Pick one, say why in two lines, and update the
module table, the container diagram and ADR-0001's
consequences. Then add a check that catches this kind of
dependency, such as a database role per module that can
reach only its own schema. List what you changed.

Judge the output

CriterionWeakStrong
Traceabilityboxes with no stated purposeevery component and decision names the driver it serves
Measurable qualities"scalable, secure, maintainable"scenarios with numbers: latency, recovery time, time to change
Trade-offsone option, all upsideeach decision names what got worse and why that is acceptable
Alternativesstraw mengenuinely different options, rejected for stated reasons
Boundariesby technical layer, shared tablesby business capability; each module owns its data and exposes an API
Dependenciesarrows in every direction, cyclesinward toward the domain; acyclic; rules listed
Fit to team12 services for 3 peopleoperational load matches team size and skills
Reversibilityall decisions treated alikehard-to-reverse decisions flagged and given more evidence
Risksnone, or a generic listspecific risks with likelihood, impact, mitigation and a cheap test
Diagramsmixed levels, unlabeled arrows, won't renderone C4 level each, titled, labeled, renders
Enforcementrules in prose onlyfitness functions that run in CI

The same checks are in every <quality_bar> on this sheet, so the model is asked to run them before it answers; the rubric is how you confirm it did.

Follow-up prompts:

Which component in your design serves no numbered driver?
Remove it or justify it.
Argue for the simplest alternative (a modular monolith /
plain layers) as strongly as you can. Where does your
recommended design lose to it?
Pre-mortem: it is 18 months later and this architecture
failed. Write the 5 most likely reasons, then say which
decision today would have prevented each.
Which of these decisions are hard to reverse? For each,
what evidence should we gather before committing, and how
cheaply can we get it?

Pitfalls

PitfallWhat it looks likeCounter it
Hype by defaultmicroservices, Kafka, Kubernetes, service mesh, GraphQL for a small teamgive team size and ops budget; "simplest architecture that meets the drivers; justify each component"
Generic qualities"highly scalable and maintainable" with no numbersdemand quality attribute scenarios with response measures
Pattern souphexagonal + CQRS + event sourcing + DDD everywhere"where does each pattern pay for itself, and where is it ceremony?"
Layer-first splittingcontrollers/, services/, repositories/ as the top-level designask for modules by business capability
Shared database between servicesseveral services read and write the same tables"each module owns its data; list every cross-module data access"
Rewrite instead of migrate"rebuild it from scratch in the new style"ask for incremental steps that each leave the app shippable (strangler fig, branch by abstraction)
Ignoring the organizationboundaries that cut across team ownershipgive the team structure; ask how Conway's law applies
Diagrams that disagree with the texta database in the diagram that the prose never mentions; arrows with no labelsask it to cross-check the diagram against the module table; render the Mermaid
Invented APIs and tool optionsplausible but nonexistent library functions or config keyscheck every library and tool option against current docs; run the rule
Stale conventionsframework versions, folder conventions or APIs from before the model's cutoffstate your versions; paste the current docs for anything version-sensitive
Agreeable reviews"the design looks solid""report only problems, ranked; find at least 5 or explain why there are fewer"
Security as an afterthoughtno mention of authentication, authorization or trust boundariesask for trust boundaries and a STRIDE threat model per boundary

References