System design
Skill ats4321/claude-engineering-skills/skills/system-design
Design NEW systems and components from first principles. Auto-load when asked to "design", "architect", or "propose" a new system, service, feature, or component; when writing a design doc or ADR; when comparing candidate architectures; when estimating capacity or load; or when planning how to deliver a design incrementally. NOT for analyzing an existing system's structure (architecture-analysis), NOT for designing the API surface itself (api-and-interface-design), and NOT for LLM-specific design decisions (llm-system-design).From its SKILL.md
npx -y skills add ats4321/claude-engineering-skills --skill system-designAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
16.2 KB, ~3.6k tokens by cl100k_base, as published. Nobody here has run it
System Design
Purpose
Design is choosing among alternatives under constraints — and a design that considered no alternatives is a guess with formatting. This skill is the discipline for new systems: clarify requirements until they are testable, enumerate constraints, compare 2–3 candidate architectures with explicit tradeoffs, reason about failure and capacity before building, record the decision as a lightweight ADR, and deliver in slices that each leave a working system.
Metadata
- Prerequisites:
codebase-onboardingandarchitecture-analysiswhen designing within an existing system (study precedent before adding to it);engineering-minimalismalways (rung 1: does this need to exist?). - Related Skills:
api-and-interface-design(the contract surface of what you design),proof-and-analysis(owns estimation mechanics),campaign-planning(executing the delivery plan),llm-system-design(LLM-specific design),documentation-practices(keeping the ADR true over time). - Owns: design docs and ADR authoring; candidate-architecture comparison; capacity estimation applied to design; failure-mode-first design; incremental delivery planning.
When to Use / When NOT to Use
Use when:
- Starting any new system, service, or component whose shape is not already dictated.
- Asked to write a design doc, proposal, or ADR.
- A feature is big enough that "just start coding" has already failed once.
- Reviewing someone else's design for completeness.
Do NOT use (load the sibling instead):
- Understanding or judging an EXISTING system's structure →
architecture-analysis. - Designing the function/API/CLI contract in detail →
api-and-interface-design. - The system centers on an LLM →
llm-system-design(then return here for the surrounding system). - The "design task" is actually a small change to existing code →
change-control; a design doc for a one-file change is process theater (engineering-minimalism). - Executing an already-approved design across many steps →
campaign-planning.
Definitions & Mental Model
- Requirement: a testable statement of what the system must do ("handles 100 uploads/min with p99 < 2s"), not an aspiration ("fast and scalable").
- Constraint: a fact you cannot design away — budget, team size, existing stack, deadline, data residency, deployment shape.
- Candidate architecture: one coherent way to satisfy the requirements; a real design compares at least two.
- ADR (Architecture Decision Record): a short, dated record of one decision — context, options considered, decision, consequences.
- Failure-mode-first design: designing what happens when each component is down/slow/wrong before polishing the happy path.
Mental model: a principal engineer designs by shrinking the space of possible systems until only defensible ones remain. Requirements and constraints do the first shrinking; candidate comparison does the second; failure and capacity reasoning eliminates the survivors that only work on the whiteboard. What remains is written down — not to bureaucratize, but because an unwritten design cannot be attacked, and a design nobody attacked is untested. The document's length is proportional to the decision's blast radius: a paragraph for a module, pages only for systems that are expensive to change later.
Core Methodology
- Decide whether a design doc is warranted (decision tree):
How expensive is this decision to reverse?
├─ Cheap (one module, easily rewritten, no data/contract lock-in)
│ → NO doc. Sketch the shape in the PR description. Build.
├─ Moderate (crosses module boundaries, adds a dependency or a
│ persistent schema, other code will call it)
│ → LIGHTWEIGHT ADR: one page — context, 2-3 options, decision,
│ consequences. Hours, not days.
└─ Expensive (new service, data model others build on, external
contract, security boundary, framework choice)
→ FULL design doc: everything in steps 2-8, reviewed by
someone incentivized to find the flaw.
- Clarify requirements until each is testable. Rewrite every aspiration as a measurable statement with a number or an observable behavior. Separate must-have from nice-to-have explicitly. A requirement you cannot test is a preference — label it as such. Ask the deletion question early: what happens if we simply don't build this? (
engineering-minimalismrung 1; if the answer is "not much," stop here and say so.) - Inventory constraints before inventing solutions. List what is fixed: existing stack and conventions, team/agent capacity, deadline, budget, data residency/privacy, deployment shape, compatibility obligations. Constraints are design inputs, not obstacles — half of all over-engineering comes from designing for constraints the project does not have.
- Enumerate 2–3 candidate architectures. For each: one paragraph describing the shape, then a shared comparison table over the axes that matter for THIS decision (complexity, failure behavior, cost, latency, operational burden, exit cost). Rules:
- Always include the simplest candidate that could possibly work — often "a cron job and a table." If the boring candidate survives comparison, it wins (
engineering-minimalism: boring over clever). - One candidate must be "extend what exists" when designing inside a system.
- A comparison where one option has no real downsides is a rigged comparison — find the downside or distrust the analysis.
- Always include the simplest candidate that could possibly work — often "a cron job and a table." If the boring candidate survives comparison, it wins (
- Reason about failure before the happy path. For each component in the leading candidate: what happens when it is down, slow, or returns garbage? Classify each failure fatal or recoverable (taxonomy owned by
architecture-analysis), decide degraded behavior, and make external effects idempotent (alsoarchitecture-analysis). A design whose failure column is empty is half a design. - Do the capacity arithmetic. Back-of-envelope, with assumptions written down: expected load, growth, per-unit cost (storage, compute, tokens, requests), and where the first bottleneck appears (estimation mechanics owned by
proof-and-analysis). The point is not precision — it is discovering the 100× surprise on paper instead of in production. If the numbers say the simple design holds to 50× current load, that is a license to stay simple. - Design the seams for replaceability. Identify which parts are most likely to change (the model, the storage engine, the delivery channel) and put a narrow typed contract there (contracts-as-seams owned by
architecture-analysis; contract craft byapi-and-interface-design). Design for deletion: the best components can be removed without archaeology. - Record the decision as an ADR. Format (keep it to a page):
- Title + date + status (proposed / accepted / superseded-by-X)
- Context: the requirement and constraints in 3–5 sentences
- Options considered: the candidates with one-line verdicts each
- Decision: what and why, in plain language
- Consequences: what gets harder, what we gave up, what would trigger revisiting
ADRs are append-only history: supersede, don't rewrite (keeping them true over time is
documentation-practices' job).
- Plan delivery in slices that each leave a working system. Order by risk: the slice that would invalidate the design ships first. Each slice has its own done-criteria and verification. (Execution of the multi-slice plan:
campaign-planning.)
Design review checklist
- Doc weight matches decision reversibility (tree in step 1)
- Every requirement testable; must-have vs nice-to-have separated
- "What if we don't build it?" answered in writing
- Constraints listed before candidates were generated
- ≥2 candidates including the simplest-that-could-work; comparison table with real downsides for every option
- Failure behavior designed per component; fatal/recoverable classified; effects idempotent
- Capacity arithmetic present with assumptions stated
- Likely-to-change parts isolated behind narrow contracts
- ADR written: context, options, decision, consequences, date
- Delivery sliced by risk, each slice independently verifiable
Discovery & Audit Commands
This domain is judgment-driven; the commands that apply are the precedent-discovery ones — run them before designing inside an existing system:
# What design decisions already exist? (respect precedent or supersede it explicitly)
find . -type d -iname "*adr*" -o -iname "*decision*" -o -iname "*rfc*" 2>/dev/null | grep -v node_modules
find . -iname "*.md" -path "*doc*" | grep -v node_modules | head
# What similar shapes already exist in this codebase? (extend-what-exists candidate)
grep -rn "class \|def \|function " --include="*.py" --include="*.ts" . | grep -iE "<domain-keyword>" | head -20
# Existing conventions the design must respect
cat CLAUDE.md CONTRIBUTING.md 2>/dev/null | head -50
# Scale reality check: how big is the system you're adding to?
find . -name "*.py" -o -name "*.ts" | grep -v node_modules | grep -v .git | xargs wc -l | tail -1
Failure Modes & Anti-patterns
| Symptom | Mistake | Correction |
|---|---|---|
| Design doc with exactly one option | No alternatives considered — a guess with formatting | 2–3 candidates including the boring one; comparison table (step 4) |
| "Scalable, robust, flexible" requirements | Aspirations instead of testable statements | Numbers and observable behaviors; label preferences as preferences (step 2) |
| Production melts at 10× load nobody predicted | Capacity arithmetic skipped | Back-of-envelope with written assumptions (step 6) |
| First outage reveals undesigned failure paths | Happy-path-only design | Failure column per component, before build (step 5) |
| Microservices for a single-team CRUD app | Designing for constraints the project doesn't have | Constraint inventory first; simplest candidate always included (steps 3–4) |
| Week-long design doc for a one-file helper | Doc weight exceeds decision weight | Reversibility tree; cheap decisions get a PR sketch (step 1) |
| "Why is it built this way?" unanswerable in a year | Decision made in chat, never recorded | One-page ADR at decision time (step 8) |
| Rigged comparison (chosen option has no downsides) | Advocacy dressed as analysis | Every option gets a real downside or the analysis is redone (step 4) |
| Big-bang delivery; nothing works until everything does | No slicing, or slices that don't run | Risk-first slices, each leaving a working system (step 9) |
| Replacing the storage engine requires touching 40 files | Likely-to-change parts not behind seams | Narrow typed contract at each volatile boundary (step 7) |
Worked Example
Task: design a nightly report generator — aggregate the day's orders and email a summary to operations.
- Doc weight: moderate — adds a schedule, touches the orders schema read-only, one consumer team. → one-page ADR.
- Requirements: report delivered by 06:00 local (testable); covers all orders closed in the prior day (testable); tolerable to miss one day (explicitly nice-to-have recovered by re-run). "Don't build it?" — ops currently runs a manual query weekly; the ask is real but small.
- Constraints: existing stack is a monolith + Postgres + a cron host; team of two; no new infrastructure budget.
- Candidates:
- A. Cron job + SQL + SMTP — one script, one crontab line. Downside: silent failure if the host is down.
- B. Queue-based worker with retry — robust delivery. Downside: introduces a broker to operate for a once-daily task.
- C. Extend the existing admin dashboard with an export — no email at all. Downside: doesn't meet the "delivered by 06:00" requirement without someone logging in. Comparison table on complexity / failure behavior / ops burden → A wins; B's robustness is disproportionate for a job whose failure costs one day and is recoverable by re-run.
- Failure design: cron host down → report missing; mitigation: the script writes a success marker, and a second trivial cron at 07:00 emails an alert if the marker is absent (failure made visible, not prevented — proportionality). Duplicate run → idempotent: report keyed by date, resend replaces.
- Capacity: 5k orders/day × 200 bytes → ~1 MB scanned; trivial for a decade of growth. Written down anyway — the arithmetic is the license to stay simple.
- Seams: delivery channel behind a
send_report(date, body)function — email today, chat webhook tomorrow, no rework upstream. - ADR: one page, options A/B/C with verdicts, decision A, consequence "no delivery guarantee beyond next-morning alert; revisit if the report becomes compliance-relevant."
- Slices: (1) query + report text verified against a hand-computed day — the risk slice; (2) email delivery; (3) the absence-alert cron.
Repository Examples
Repo facts below are point-in-time illustrations (as of 2026-07-04) — examples, never assumptions about your system.
- prism (
~/prism) — failure-mode-first design visible in the artifact: every component has a designed failure behavior (OllamaUnavailableErroraborts fast; per-chunk timeouts degrade; missingGITHUB_TOKENwarns and skips posting), external effects are idempotent (deletes own prior comments), and load is bounded by design (Semaphore(5),MAX_FILES_PER_PR=10,MAX_LINES_PER_CHUNK=120) — the step-5/6 columns filled in, in code. - orphy (
~/orphy) — seams for replaceability:FeedbackResultdecouples generation from delivery with a swappableDeliveryChannel(text|audio) designed in from day one — the step-7 discipline; phases joined by JSON contracts so implementations swap without downstream change. - asver (
~/asver) — constraints as design inputs: commit "Remove server build from package.json for static deployment" shows the deployment-shape constraint reshaping the build (motive partly inferred — Hypothesis). - ragit (
~/ragit) — the simplest-candidate-that-works, shipped: a 4-module, ~665-line local pipeline with no server, no queue, no config system — proportional to a single-operator tool's requirements.
Validation Criteria
You applied this skill correctly when:
- The doc's weight matches the reversibility tree, and you can defend the weight choice.
- A reviewer can find at least two real candidates, each with a stated downside.
- Every requirement in the doc is testable; someone could write the acceptance check from it.
- The failure column exists for every component, with fatal/recoverable classifications.
- The capacity math is present, and its assumptions are attackable (that is the point).
- The ADR answers "why is it built this way?" without oral history.
- Slice 1 of the delivery plan is the highest-risk slice, and it runs end to end.
Provenance & Maintenance
- Sources:
~/prism,~/orphy,~/asver,~/ragit— investigated 2026-07-04. Owner doctrine (minimalism, proportionality) confirmed 2026-07-04. Skill authored 2026-07-06; methodology is repo-independent. - Assumptions: the ADR format here is the lightweight industry-common shape (context/options/decision/consequences); teams with an established ADR template should use theirs. Repo constants are point-in-time.
- Re-verification commands:
grep -rn "Semaphore\|MAX_FILES_PER_PR" ~/prism/prism ~/prism/.env.example grep -rn "DeliveryChannel\|FeedbackResult" ~/orphy -r 2>/dev/null | head - Likely to drift: example repos' bounds/constants; the asver inference (confirm or delete); ADR conventions if the owner adopts a formal template.
- Maintenance checklist:
- Re-run re-verification; re-stamp Repository Examples.
- If any owner repo gains real ADRs, add one as a case study.
- Confirm cross-referenced skills still exist under their directory names.
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.
Gives 0 of the 12 instructions most architecture codebase skills give in ~3.6k tokens
Counted across 811 of the 1,134 authors here whose files we hold, read 2026-08-07
- Ask the user which candidate to explorein 45 of 811, across 15 files
- Apply the deletion test to suspected shallow modulesin 43 of 811, across 15 files
- Read any relevant architecture decision records firstin 31 of 811, across 8 files
- Use exact glossary terms in every suggestionin 30 of 811, across 10 files
- Accept dependencies instead of creating themin 24 of 811, across 5 files
- Include before and after visualisations for each candidatein 24 of 811, across 5 files
- Read the domain glossary before exploringin 24 of 811, across 6 files
- Return results instead of producing side effectsin 23 of 811, across 4 files
- Explore the codebase for shallow modules and frictionin 23 of 811, across 3 files
- Introduce seams only where things varyin 22 of 811, across 3 files
- Reduce the number of methodsin 21 of 811, across 2 files
- Design deep modules with small interfacesin 21 of 811, across 3 files
Said here and by no other author read
- write requirements as testable statements
- inventory constraints before inventing solutions
- enumerate two to three candidate architectures
- include the simplest possible working candidate
- reason about failure before the happy path
- perform capacity arithmetic with assumptions
Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.