Review a System Design
Read a design, stress-test it against real failure modes and scale pressures, and produce honest feedback — not a rubber stamp, not a wishlist, but the kind of review that would surface issues before prod does.
Decision tree
- What are you reviewing?
- A written design doc (markdown file, paste, URL) → read it fully, then follow "Full review" below
- A diagram only, no doc → ask for context: goals, scale, constraints. You can't review architecture from a picture alone.
- A vague idea ("what do you think of using X for Y?") → this is a discussion, not a review. Talk through trade-offs; offer to run a real review once there's a concrete design.
- An existing production system → read code and
.context/ first, then review the implemented architecture against what it should do
- A PR introducing an architectural change → scope the review to the change, but pull in surrounding context from the codebase
Full review
1. Understand what you're reviewing
Before criticizing anything, make sure you understand:
- Goal — what is this system supposed to do?
- Constraints — scale targets, latency/availability requirements, team size, budget, existing stack
- Context — what's already in place, what's being replaced, what's out of scope
If the doc doesn't say, ask — don't review against imagined requirements. A design is only wrong relative to something; make sure you know what that something is.
2. Stress-test with these lenses
Walk each lens below and write findings as you go. Not every lens applies to every design — skip the ones that don't fit, but skip consciously.
Failure modes
- What happens when each component is slow? Down? Returns garbage?
- Are there single points of failure? Is that acceptable?
- What's the blast radius of a bad deploy? A runaway query? A poisoned message?
- Can the system recover without human intervention? Within the RTO?
- Are timeouts set everywhere? Retries bounded? Circuit breakers where they matter?
Scaling cliffs
- Where's the bottleneck at 10x current load? At 100x?
- Which component is hardest to scale — stateful DB, single-writer queue, a sync RPC chain?
- Are hot keys / hot rows going to bite? (think: celebrity users, popular products, global counters)
- Is fanout bounded? (1 request → N downstream calls — what's N worst case?)
- Do caches thunder-herd on cold start or invalidation?
Data & consistency
- Who owns each piece of data? Is there exactly one source of truth?
- How are cross-service writes handled? (dual-write risk, outbox, sagas?)
- Are reads allowed to be stale? Where? For how long?
- What happens on concurrent writes to the same record?
- How do schema migrations happen without downtime?
Security
- Is input validated at every boundary?
- AuthN and AuthZ — clear, enforced, not just "we'll add it later"
- Secrets management — how, where, rotated?
- PII handling — GDPR delete flow, audit trail, data residency
- Rate limiting on public endpoints
- What does an attacker gain by compromising each component?
Operability
- Can oncall debug this at 3am? What dashboards, logs, traces exist?
- What pages a human vs what's just a ticket?
- Is the deploy story clear? Rollback? Feature flags?
- Runbooks for known failure modes?
- Is cost observable — can you tell who/what is burning money?
Design coherence
- Does the architecture match the stated requirements, or is it cargo-culted from somewhere else?
- Are tech choices justified? ("We picked X because Y" — is Y actually true?)
- Are there simpler alternatives that were genuinely considered?
- Is anything over-engineered for the actual scale? Under-engineered?
- Are service boundaries drawn along responsibility lines or along org-chart lines?
Stack defaults compliance
Check the design against the convention references in workflow and codebase skills (../data-modeling/references/, ../../../codebase/skills/api-design/references/, ../architecture/references/). If the planning:requirements skill is installed, use its NFR checklist for non-functional coverage; otherwise evaluate NFRs from the design text and ask for missing targets. Deviations aren't wrong, but they should be intentional and documented. Flag if:
- Async work is handled inline instead of via Queues (for anything >50ms)
- Write endpoints lack
Idempotency-Key enforcement
- AuthZ is only enforced in handlers (should be middleware + service layer + RLS)
- Error responses don't use RFC 7807 Problem Details
- Outbound calls lack per-operation timeouts
- Multi-table writes aren't in a transaction
- No outbox for cross-system side effects (direct queue publish from handler)
- IDs aren't prefixed ULIDs
- Data residency isn't EU-primary without stated reason
- PII fields lack encryption at rest
- Breaking schema changes use single-step migration instead of expand-contract
- Missing
tenant_id + RLS on tenant-scoped tables
- Cron jobs run logic inline instead of enqueuing onto Queues
- File uploads proxy bytes through the API instead of using presigned URLs to R2
- Public endpoints lack rate limiting (per-user, not just per-IP)
- Feature flags have no cleanup plan (release flags should be removed after full rollout)
- D1 used for multi-tenant or compliance-sensitive data where Neon would be more appropriate (or vice versa without justification)
- Cloudflare Pages used instead of Workers with Static Assets for new projects
3. Write the review
Produce a structured review document. Write it back to the user in chat for discussion, and optionally save it to .context/architecture/reviews/<design>-review-<date>.md if they want a record.
Structure:
# Review: <design name>
Reviewer: Agent
Date: <YYYY-MM-DD>
## Summary
<2-3 sentences: overall take, most important finding>
## What works
<Things the design gets right. This is not flattery — note real strengths so they don't get lost in a refactor.>
## Findings
### [CRITICAL] <finding title>
**Problem:** <what's wrong>
**Why it matters:** <consequence under realistic conditions>
**Suggestion:** <one or two concrete ways to fix it>
### [MAJOR] <finding title>
...
### [MINOR] <finding title>
...
### [QUESTION] <finding title>
**Question:** <something the doc doesn't answer that a reviewer would need to know>
## Open questions for the author
<Things you couldn't review because the doc didn't say>
4. Severity guide
Use these to force calibration — don't label everything CRITICAL.
| Severity |
Meaning |
Example |
| CRITICAL |
Will cause incidents in production or block a core requirement |
Dual-write between DB and queue with no outbox → lost events |
| MAJOR |
Significant risk or cost you'd want to address before building |
Single Redis instance for session store at 99.95% target |
| MINOR |
Worth fixing but won't sink the project |
Missing rate limits on internal admin endpoint |
| QUESTION |
Reviewer can't assess without more info |
"What's the expected write/read ratio on the orders table?" |
5. Keep it useful
- Be specific — "this will fall over under load" is useless; "Postgres write throughput caps around 5k/s on the current Neon tier; the design assumes 10k/s peak — what's the plan?" is a review
- Don't rewrite the design — propose fixes, but a review is not a redesign. If the whole thing is wrong, say so clearly and suggest a reset rather than editing every section.
- Rank honestly — the author will triage by severity. If everything is critical, nothing is.
- Call out what's good — designs get refactored and the good parts often get lost. Name them so they survive.
- Ask, don't assume — when you can't tell if something is a gap or an omission from the doc, put it in "Questions" rather than "Findings"
6. Write so a junior can learn from the review
Reviews are a teaching tool. The author might be senior; the next person to read the doc might not be. That means:
- When you name a failure mode, explain it in one line. Don't just say "thundering herd on cache expiry" — add "(when a cached value expires, every waiting request hits the backend at once, overwhelming it)". The extra sentence costs nothing and the finding becomes actionable without the reader having to google.
- When you cite a pattern as a fix, explain what it is. "Add a circuit breaker (a wrapper that stops calling a failing dependency after N errors, giving it time to recover)" beats "add a circuit breaker".
- Prefer plain phrasing. "This design has a SPOF" → "This design has a single point of failure — if the Redis instance goes down, every request fails. See the 'Availability' row below."
- Say why a finding matters in concrete terms. Not "risks dual-write inconsistency" but "if the Stripe webhook arrives while the DB write is still in flight, the order will look unpaid forever — no retry path exists". A junior reading this should be able to picture the incident.
- If a reviewer needs deep domain knowledge to understand a finding, say so explicitly so the author knows who to loop in.
Embedded explainers make the review useful to a wider audience — including weaker LLM models that will read this doc later as context.
Key references
| File |
Covers |
../data-modeling/references/ |
Data conventions — IDs, naming, tenancy, soft delete, JSONB, audit, migrations (one file per topic) |
../../../codebase/skills/api-design/references/ |
API conventions — HTTP, errors, auth, pagination, API patterns (one file per topic) |
../architecture/references/ |
Infra conventions — async, resilience, observability, deploy, testing, privacy (one file per topic) |
planning:requirements |
Companion requirements skill — use for NFR coverage if the plugin is installed |
Cross-references
| Situation |
Action |
| The design is missing a section entirely (e.g., no NFRs) |
Flag the gap; hand off to planning:requirements for NFRs or documentation:write-design-doc for structure if installed |
| The user wants the design rewritten after review |
Hand off to architecture plus documentation:write-design-doc with findings as input if installed |
| A finding deserves a permanent decision record |
Suggest documentation:write-adr to capture the resolution if installed |
1---2name: design-review3description: Reviews and critiques an existing or proposed system design — flags single points of failure, missing non-functional requirements, scaling bottlenecks, security gaps, operational blind spots, unjustified tech choices, and places where the design will fall over under load or failure. Produces a structured review with severity-tagged findings, not just vibes. Use when the user asks for a second opinion on an architecture, requests a design review, wants feedback on a proposed system, pastes a design doc, or says things like "review this design", "what's wrong with X", "poke holes in this", or "is this a good architecture".4---56# Review a System Design7Read a design, stress-test it against real failure modes and scale pressures, and produce honest feedback — not a rubber stamp, not a wishlist, but the kind of review that would surface issues before prod does.89## Decision tree10- What are you reviewing?11 - **A written design doc** (markdown file, paste, URL) → read it fully, then follow "Full review" below12 - **A diagram only, no doc** → ask for context: goals, scale, constraints. You can't review architecture from a picture alone.13 - **A vague idea** ("what do you think of using X for Y?") → this is a discussion, not a review. Talk through trade-offs; offer to run a real review once there's a concrete design.14 - **An existing production system** → read code and `.context/` first, then review the *implemented* architecture against what it should do15 - **A PR introducing an architectural change** → scope the review to the change, but pull in surrounding context from the codebase1617## Full review1819### 1. Understand what you're reviewing20Before criticizing anything, make sure you understand:2122- **Goal** — what is this system supposed to do?23- **Constraints** — scale targets, latency/availability requirements, team size, budget, existing stack24- **Context** — what's already in place, what's being replaced, what's out of scope2526If the doc doesn't say, ask — don't review against imagined requirements. A design is only wrong relative to something; make sure you know what that something is.2728### 2. Stress-test with these lenses29Walk each lens below and write findings as you go. Not every lens applies to every design — skip the ones that don't fit, but skip *consciously*.3031#### Failure modes32- What happens when each component is slow? Down? Returns garbage?33- Are there single points of failure? Is that acceptable?34- What's the blast radius of a bad deploy? A runaway query? A poisoned message?35- Can the system recover without human intervention? Within the RTO?36- Are timeouts set everywhere? Retries bounded? Circuit breakers where they matter?3738#### Scaling cliffs39- Where's the bottleneck at 10x current load? At 100x?40- Which component is hardest to scale — stateful DB, single-writer queue, a sync RPC chain?41- Are hot keys / hot rows going to bite? (think: celebrity users, popular products, global counters)42- Is fanout bounded? (1 request → N downstream calls — what's N worst case?)43- Do caches thunder-herd on cold start or invalidation?4445#### Data & consistency46- Who owns each piece of data? Is there exactly one source of truth?47- How are cross-service writes handled? (dual-write risk, outbox, sagas?)48- Are reads allowed to be stale? Where? For how long?49- What happens on concurrent writes to the same record?50- How do schema migrations happen without downtime?5152#### Security53- Is input validated at every boundary?54- AuthN and AuthZ — clear, enforced, not just "we'll add it later"55- Secrets management — how, where, rotated?56- PII handling — GDPR delete flow, audit trail, data residency57- Rate limiting on public endpoints58- What does an attacker gain by compromising each component?5960#### Operability61- Can oncall debug this at 3am? What dashboards, logs, traces exist?62- What pages a human vs what's just a ticket?63- Is the deploy story clear? Rollback? Feature flags?64- Runbooks for known failure modes?65- Is cost observable — can you tell who/what is burning money?6667#### Design coherence68- Does the architecture match the stated requirements, or is it cargo-culted from somewhere else?69- Are tech choices justified? ("We picked X because Y" — is Y actually true?)70- Are there simpler alternatives that were genuinely considered?71- Is anything over-engineered for the actual scale? Under-engineered?72- Are service boundaries drawn along responsibility lines or along org-chart lines?7374#### Stack defaults compliance75Check the design against the convention references in workflow and codebase skills (`../data-modeling/references/`, `../../../codebase/skills/api-design/references/`, `../architecture/references/`). If the `planning:requirements` skill is installed, use its NFR checklist for non-functional coverage; otherwise evaluate NFRs from the design text and ask for missing targets. Deviations aren't wrong, but they should be intentional and documented. Flag if:7677- Async work is handled inline instead of via Queues (for anything >50ms)78- Write endpoints lack `Idempotency-Key` enforcement79- AuthZ is only enforced in handlers (should be middleware + service layer + RLS)80- Error responses don't use RFC 7807 Problem Details81- Outbound calls lack per-operation timeouts82- Multi-table writes aren't in a transaction83- No outbox for cross-system side effects (direct queue publish from handler)84- IDs aren't prefixed ULIDs85- Data residency isn't EU-primary without stated reason86- PII fields lack encryption at rest87- Breaking schema changes use single-step migration instead of expand-contract88- Missing `tenant_id` + RLS on tenant-scoped tables89- Cron jobs run logic inline instead of enqueuing onto Queues90- File uploads proxy bytes through the API instead of using presigned URLs to R291- Public endpoints lack rate limiting (per-user, not just per-IP)92- Feature flags have no cleanup plan (release flags should be removed after full rollout)93- D1 used for multi-tenant or compliance-sensitive data where Neon would be more appropriate (or vice versa without justification)94- Cloudflare Pages used instead of Workers with Static Assets for new projects9596### 3. Write the review97Produce a structured review document. Write it back to the user in chat for discussion, and optionally save it to `.context/architecture/reviews/<design>-review-<date>.md` if they want a record.9899Structure:100101```markdown102# Review: <design name>103Reviewer: Agent104Date: <YYYY-MM-DD>105106## Summary107108<2-3 sentences: overall take, most important finding>109110## What works111112<Things the design gets right. This is not flattery — note real strengths so they don't get lost in a refactor.>113114## Findings115116### [CRITICAL] <finding title>117**Problem:** <what's wrong>118**Why it matters:** <consequence under realistic conditions>119**Suggestion:** <one or two concrete ways to fix it>120121### [MAJOR] <finding title>122...123124### [MINOR] <finding title>125...126127### [QUESTION] <finding title>128**Question:** <something the doc doesn't answer that a reviewer would need to know>129130## Open questions for the author131132<Things you couldn't review because the doc didn't say>133```134135### 4. Severity guide136Use these to force calibration — don't label everything CRITICAL.137138|Severity|Meaning|Example|139|---|---|---|140|**CRITICAL**|Will cause incidents in production or block a core requirement|Dual-write between DB and queue with no outbox → lost events|141|**MAJOR**|Significant risk or cost you'd want to address before building|Single Redis instance for session store at 99.95% target|142|**MINOR**|Worth fixing but won't sink the project|Missing rate limits on internal admin endpoint|143|**QUESTION**|Reviewer can't assess without more info|"What's the expected write/read ratio on the orders table?"|144145### 5. Keep it useful146- **Be specific** — "this will fall over under load" is useless; "Postgres write throughput caps around 5k/s on the current Neon tier; the design assumes 10k/s peak — what's the plan?" is a review147- **Don't rewrite the design** — propose fixes, but a review is not a redesign. If the whole thing is wrong, say so clearly and suggest a reset rather than editing every section.148- **Rank honestly** — the author will triage by severity. If everything is critical, nothing is.149- **Call out what's good** — designs get refactored and the good parts often get lost. Name them so they survive.150- **Ask, don't assume** — when you can't tell if something is a gap or an omission from the doc, put it in "Questions" rather than "Findings"151152### 6. Write so a junior can learn from the review153Reviews are a teaching tool. The author might be senior; the next person to read the doc might not be. That means:154155- **When you name a failure mode, explain it in one line.** Don't just say "thundering herd on cache expiry" — add "(when a cached value expires, every waiting request hits the backend at once, overwhelming it)". The extra sentence costs nothing and the finding becomes actionable without the reader having to google.156- **When you cite a pattern as a fix, explain what it is.** "Add a circuit breaker (a wrapper that stops calling a failing dependency after N errors, giving it time to recover)" beats "add a circuit breaker".157- **Prefer plain phrasing.** "This design has a SPOF" → "This design has a single point of failure — if the Redis instance goes down, every request fails. See the 'Availability' row below."158- **Say why a finding matters in concrete terms.** Not "risks dual-write inconsistency" but "if the Stripe webhook arrives while the DB write is still in flight, the order will look unpaid forever — no retry path exists". A junior reading this should be able to picture the incident.159- **If a reviewer needs deep domain knowledge to understand a finding, say so explicitly** so the author knows who to loop in.160161Embedded explainers make the review useful to a wider audience — including weaker LLM models that will read this doc later as context.162163## Key references164|File|Covers|165|---|---|166|`../data-modeling/references/`|Data conventions — IDs, naming, tenancy, soft delete, JSONB, audit, migrations (one file per topic)|167|`../../../codebase/skills/api-design/references/`|API conventions — HTTP, errors, auth, pagination, API patterns (one file per topic)|168|`../architecture/references/`|Infra conventions — async, resilience, observability, deploy, testing, privacy (one file per topic)|169|`planning:requirements`|Companion requirements skill — use for NFR coverage if the plugin is installed|170171## Cross-references172|Situation|Action|173|---|---|174|The design is missing a section entirely (e.g., no NFRs)|Flag the gap; hand off to `planning:requirements` for NFRs or `documentation:write-design-doc` for structure if installed|175|The user wants the design rewritten after review|Hand off to `architecture` plus `documentation:write-design-doc` with findings as input if installed|176|A finding deserves a permanent decision record|Suggest `documentation:write-adr` to capture the resolution if installed|