[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-microsoft-design-philosophy-linux":3,"mdc-yyzuqv-key":36,"related-repo-microsoft-design-philosophy-linux":1891,"related-org-microsoft-design-philosophy-linux":1972},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":11,"stars":25,"repoUrl":26,"updatedAt":27,"license":28,"forks":29,"topics":30,"repo":31,"sourceUrl":34,"mdContent":35},"design-philosophy-linux","apply Unix and Linux design philosophy","The Unix\u002FLinux design philosophy as a lens for system design — mechanism vs policy, composability, small tools, text streams, convention over configuration, and the principle of least surprise. Use when evaluating designs for composability, simplicity, or separation of concerns.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},"microsoft","Microsoft","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Fmicrosoft.png",[12,16,19,22],{"name":13,"slug":14,"type":15},"Architecture","architecture","tag",{"name":17,"slug":18,"type":15},"System Design","system-design",{"name":20,"slug":21,"type":15},"Linux","linux",{"name":23,"slug":24,"type":15},"Engineering","engineering",0,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Famplifier-bundle-systems-design","2026-05-13T06:14:50.770309",null,1,[],{"repoUrl":26,"stars":25,"forks":29,"topics":32,"description":33},[],"Systems-design capabilities for Amplifier sessions.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Famplifier-bundle-systems-design\u002Ftree\u002FHEAD\u002Fskills\u002Fdesign-philosophy-linux","---\nname: design-philosophy-linux\ndescription: \"The Unix\u002FLinux design philosophy as a lens for system design — mechanism vs policy, composability, small tools, text streams, convention over configuration, and the principle of least surprise. Use when evaluating designs for composability, simplicity, or separation of concerns.\"\n---\n\n# Design Philosophy: Unix\u002FLinux\n\nThe Unix philosophy as a thinking tool for modern system design.\n\n---\n\n## Mechanism vs Policy\n\nThe deepest principle in Unix. The kernel provides *mechanisms* (process scheduling, file descriptors, memory mapping). User-space provides *policy* (which processes run, what files mean, how memory is used). The kernel doesn't have opinions about your workflow. It gives you the tools to build any workflow.\n\n**The litmus test:** Could two reasonable users want different behavior here? If yes, you're looking at *policy* — don't hardcode it. Provide a mechanism and let the caller decide.\n\n**How this applies broadly:**\n\n- **Frameworks provide mechanisms; applications provide policy.** A web framework gives you routing, middleware, and request handling. It should not decide your authentication strategy, your URL naming conventions, or your error page content. When a framework makes policy decisions for you, it works until your policy diverges — then you fight the framework.\n- **Libraries vs. frameworks** is often a mechanism-vs-policy question. A library gives you mechanisms you call. A framework calls your code within its policy structure. Prefer libraries when the domain is well-understood and teams have strong opinions. Prefer frameworks when teams need guardrails and the policy is genuinely standard.\n- **Configuration systems** should separate mechanism (how config is loaded, merged, validated) from policy (what the config values mean, what defaults are appropriate). The mechanism should be boring. The policy is the interesting part.\n\n**Design evaluation questions:**\n\n- Where in this design are mechanism and policy entangled? Can they be separated?\n- When this system's users inevitably want different behavior, which parts will they need to fork vs. configure?\n- Are we embedding today's policy decisions into tomorrow's mechanism layer?\n\n**The failure mode:** Over-separating mechanism from policy creates systems that are infinitely flexible and impossible to use out of the box. X11 separated mechanism from policy so aggressively that every desktop environment had to reinvent window management from scratch. The mechanism layer should be opinionated enough to be useful — just not so opinionated that it precludes valid alternatives.\n\n---\n\n## Do One Thing Well\n\nThe most cited and most misunderstood Unix principle. `grep` searches. `sort` sorts. `uniq` deduplicates. Each does one thing, does it thoroughly, and handles edge cases within its domain. The key word is *well*, not *small*.\n\n**What this actually means:**\n\nA component should have a *clear responsibility boundary*. Everything inside that boundary, it handles completely. Everything outside, it delegates. `grep` doesn't sort its output because sorting is outside its boundary. But `grep` handles binary files, compressed input, recursive directories, regex dialects, and colorized output — because those are all within \"searching text.\"\n\n**How microservices got this wrong:** \"Do one thing\" was interpreted as \"be small.\" Teams created services so thin they couldn't do anything useful alone. A \"user service\" that only stores user records but can't validate an email address. A \"notification service\" that can't template a message. The result: every operation requires orchestrating five services, and the *real* logic lives in the orchestration layer — which is now doing everything and doing it badly.\n\n**The real principle:** Draw clear responsibility boundaries. A component owns a *coherent* piece of functionality, not a *minimal* piece. The question isn't \"Is this small enough?\" but \"If I need to change how X works, do I change exactly one component?\"\n\n**Design evaluation questions:**\n\n- Can you describe what this component does in one sentence without using \"and\"?\n- If the requirements for this responsibility change, how many components must change?\n- Is this component thin because its responsibility is naturally narrow, or because we artificially split a coherent responsibility?\n\n**The tension:** \"Do one thing well\" is in tension with \"provide a complete solution.\" Unix resolves this through composition — the *pipeline* provides the complete solution while each tool provides one step. Your system needs an equivalent composition mechanism. If you don't have one, making components smaller just makes the system harder to use.\n\n---\n\n## Text Streams as Universal Interface\n\nUnix programs communicate through text streams. The format is simple enough that any program can produce and consume it. This means any program can connect to any other program, even programs that were written decades apart by people who never met.\n\n**The power of a universal interchange format:**\n\nThe magic isn't text. The magic is *universality*. When every component speaks the same format, the number of possible integrations is N (one adapter per component), not N² (one adapter per pair). You pay for this with type safety — text streams carry no schema, no types, no validation. That's the trade.\n\n**How this maps to modern systems:**\n\n| Unix Concept | Modern Equivalent | Tradeoff |\n|---|---|---|\n| Text streams | JSON payloads | Human-readable, schema-optional, verbose |\n| Pipes | HTTP requests | Universal, stateless, high overhead per call |\n| Signals | Events\u002Fwebhooks | Async notification, no return value |\n| Files | Object storage \u002F REST resources | Addressable, persistent, no push notification |\n| stdin\u002Fstdout | Request body \u002F response body | Clear directionality, one-shot |\n| Environment vars | Configuration injection | Implicit, global, stringly-typed |\n\n**The tradeoff between universal and typed interfaces:**\n\n- **Universal interfaces** (text, JSON, HTTP) are simple to adopt, compose freely, and degrade gracefully. But they're lossy — you can't express \"this field is an ISO-8601 timestamp\" in plain JSON without a schema sidecar.\n- **Typed interfaces** (protobuf, gRPC, GraphQL with schemas) are safe, self-documenting, and enable tooling. But they're rigid — every interface change requires coordinated updates, and composition requires adapters.\n- **The Unix bias is toward universality.** You can always add validation on top of a universal format. You can't easily add universality on top of a typed format.\n\n**Design evaluation questions:**\n\n- What is the \"text stream\" of this system — the universal format everything can speak?\n- Could a component written by a different team, in a different language, five years from now, connect to this interface without special knowledge?\n- Are we paying the cost of typed interfaces (coordination, rigidity) and actually getting the benefit (safety, tooling)?\n\n---\n\n## Composability Over Features\n\n`cat access.log | grep 404 | cut -d' ' -f7 | sort | uniq -c | sort -rn | head -20`\n\nNobody designed a \"top 20 not-found URLs\" feature. The feature emerged from composition. This is the central insight: **composable systems gain features over time without changing existing components.**\n\n**Stdin\u002Fstdout discipline:**\n\nWhat makes Unix tools composable isn't their size — it's their *discipline*. Each tool reads from stdin, writes to stdout, and reports errors to stderr. This discipline is what enables arbitrary connection. Without it, composition is accidental at best.\n\n**The equivalent disciplines for modern systems:**\n\n- **API design:** Accept the common format. Return the common format. Don't require callers to know your internal model. REST APIs that accept JSON and return JSON compose. APIs that require bespoke SDKs don't.\n- **Event systems:** Emit events that describe what happened, not what the listener should do. `OrderPlaced { orderId, items, total }` composes. `SendConfirmationEmail { to, template }` doesn't — it embeds policy in the event.\n- **Plugin architectures:** Define a minimal interface. Accept any implementation. The plugin boundary is the \"pipe\" — the more assumptions it carries, the fewer plugins are possible.\n- **Data pipelines:** Transform data, emit data. Don't hold state between records unless the transformation requires it. Stateless transforms compose arbitrarily. Stateful ones require careful ordering.\n\n**The composability test:** Can someone use this in a way I didn't anticipate? If your component can only be used in the one workflow you designed it for, it's not composable — it's a step in a procedure.\n\n**Design evaluation questions:**\n\n- If I remove this component from the pipeline, can I replace it with something else that speaks the same interface?\n- Does this component pull its dependencies, or are dependencies pushed to it?\n- Could a user pipe the output of this into something I've never heard of?\n\n**The failure mode:** Composability fetishism. Not everything needs to compose. A user-facing application is a *composition* — it should present a cohesive experience, not expose its internal pipes. Compose at the infrastructure layer. Integrate at the product layer.\n\n---\n\n## Convention Over Configuration\n\nUnix is full of conventions. Config lives in `\u002Fetc`. User config lives in `~\u002F.config` (XDG) or `~\u002F.\u003Capp>`. Executables live in `\u002Fusr\u002Fbin` or `\u002Fusr\u002Flocal\u002Fbin`. Logs go to `\u002Fvar\u002Flog`. Temp files go to `\u002Ftmp`. None of this is enforced by the kernel — it's pure convention. And it works because everyone follows it.\n\n**Why conventions reduce cognitive load:**\n\nEvery decision a user doesn't have to make is cognitive budget freed for the decisions that matter. When you `apt install nginx`, you know the config is in `\u002Fetc\u002Fnginx\u002F`, the logs are in `\u002Fvar\u002Flog\u002Fnginx\u002F`, and the binary is in `\u002Fusr\u002Fsbin\u002F`. You didn't read the docs to learn this. You just knew, because convention.\n\n**The 80\u002F20 rule of configuration:**\n\n- **The common case should require zero configuration.** Sensible defaults that work for 80% of users.\n- **The uncommon case should be configurable, not impossible.** Flags, config files, environment variables — progressive disclosure of complexity.\n- **The rare case can require code.** Plugins, extensions, custom builds. It's okay if the 1% case is hard.\n\n**How this maps to system design:**\n\n- **Directory\u002Ffile structure:** Establish conventions early. Where do configs go? Where do logs go? Where do plugins go? Document it once, then rely on it everywhere.\n- **Naming conventions:** `GET \u002Fusers`, `POST \u002Fusers`, `GET \u002Fusers\u002F:id`. REST naming conventions mean you can often guess an API without reading docs.\n- **Error formats:** One error format for the whole system. `{ \"error\": { \"code\": \"NOT_FOUND\", \"message\": \"...\" } }`. Don't make callers handle five different error shapes.\n- **Configuration hierarchy:** CLI flags override environment variables override config files override defaults. This isn't arbitrary — it's a convention that every Unix tool follows, and your users expect it.\n\n**The failure mode: invisible assumptions.**\n\nWhen conventions become so ingrained that nobody documents them, they become invisible assumptions. New team members violate them without knowing they exist. The convention calcifies into a trap. Conventions must be:\n\n1. **Documented** — in a place people actually look.\n2. **Enforced** — by linters, tests, or at minimum code review.\n3. **Discoverable** — a new developer should be able to find them within their first day.\n\n**Design evaluation questions:**\n\n- What would a reasonable default be for this setting? Is there any reason not to use it?\n- How many configuration options does this system have? For each one, what percentage of users will ever change it?\n- If a new developer joins, how long until they can predict where things are without asking?\n\n---\n\n## Silence is Golden\n\nRun `cp file1 file2`. If it succeeds, it prints nothing. You only hear from it if something goes wrong. This isn't laziness — it's design. Silent success means the output stream carries only signal. If every command printed \"Success!\", pipelines would drown in noise.\n\n**The principle:** Don't produce output unless you have something the user didn't already know. Success is expected — don't announce it. Failure is unexpected — report it clearly.\n\n**How this applies to modern systems:**\n\n- **Logging levels exist for a reason.** If your service logs every successful request at INFO level, you've made INFO useless. Log the *surprising* things: the request that took 10x longer than usual, the retry that succeeded on the third attempt, the config value that was overridden. DEBUG is for \"I'm actively investigating.\" INFO is for \"an operator should see this over time.\" WARN is for \"something is degraded.\" ERROR is for \"something is broken.\"\n- **API responses:** A `204 No Content` is the Unix-philosophy response to a successful DELETE. The status code tells you it worked. An empty body tells you there's nothing more to say. Don't wrap every response in `{ \"status\": \"success\", \"message\": \"Operation completed successfully\" }` — that's noise masquerading as helpfulness.\n- **Error handling:** When something fails, say *what* failed, *why* it failed, and *what the user can do about it*. Don't say \"An error occurred.\" That's the error-handling equivalent of printing \"Success!\" on every operation — technically true and completely useless.\n- **CLI output:** Default to quiet. Add `-v` for verbose. Add `-vv` for debug. Never make the user pipe through `grep -v` to find the actual output.\n\n**The principle of least surprise:**\n\nRelated but distinct: the system should behave the way the user expects. If a function is called `delete()`, it should delete — not archive, not soft-delete, not mark-for-deletion. If it does something other than delete, call it something other than `delete()`.\n\nLeast surprise is evaluated from the user's perspective, not the implementer's. What a user expects depends on their experience and the conventions of the domain. A Unix user expects `rm` to be permanent. A Google Docs user expects delete to be recoverable. Neither is wrong — but surprising the user is always wrong.\n\n**Design evaluation questions:**\n\n- If this operation succeeds, does the user need to be told? Or can they infer it from context?\n- What does this function\u002Fendpoint\u002Fcommand name imply to someone who hasn't read the docs?\n- If I read the logs from a healthy system running for a week, how much of it is noise?\n\n---\n\n## Everything is a File\n\nIn Unix, devices are files (`\u002Fdev\u002Fsda`), processes are files (`\u002Fproc\u002F1234`), network sockets are files, pipes are files. You interact with all of them using the same system calls: `open`, `read`, `write`, `close`. Learn the file interface once, and you can interact with anything.\n\n**The power of uniform interfaces:**\n\nA uniform interface reduces the API surface area a user must learn. Instead of \"here are 15 different ways to interact with 15 different things,\" it's \"here's one way to interact with everything.\" The user pays a fixed learning cost and gets access to the entire system.\n\n**How this maps to modern systems:**\n\n| Unix | Modern Equivalent | What's Uniform |\n|---|---|---|\n| Everything is a file | REST: everything is a resource | CRUD operations (GET\u002FPOST\u002FPUT\u002FDELETE) |\n| Everything is a file | Kubernetes: everything is a manifest | Declare desired state in YAML, `kubectl apply` |\n| Everything is a file | Event systems: everything is an event | Publish, subscribe, replay |\n| Everything is a file | Git: everything is an object | Hash-addressable, immutable content |\n| Everything is a file | S3: everything is an object | PUT, GET, DELETE with a key |\n\n**The power:**\n\n- **Tooling compounds.** Any tool that works with the uniform interface works with everything. `kubectl get` works on pods, services, deployments, custom resources — anything that speaks the Kubernetes resource interface. One tool, infinite applicability.\n- **Learning compounds.** Once you understand the resource model, every new resource type is immediately approachable. You don't start from zero each time.\n- **Composition is free.** Components that speak the same interface can be connected without adapters.\n\n**The limits:**\n\nNot everything maps cleanly to one interface. Files have a natural metaphor for \"read this data\" but a strained metaphor for \"subscribe to changes.\" REST has a natural metaphor for CRUD but a strained metaphor for long-running operations, batch processing, or real-time streams. When the uniform interface doesn't fit, you have two bad options: torture the metaphor (POST \u002Forders\u002Fbatch-process-and-notify-async) or break the uniformity (add a WebSocket endpoint alongside REST).\n\n**Design evaluation questions:**\n\n- What is the \"file\" in this system — the one abstraction everything maps to?\n- Does the uniform interface fit the actual operations, or are we torturing the metaphor?\n- What can't be expressed through this interface? Is that acceptable, or does it indicate the wrong abstraction?\n\n---\n\n## Applying the Philosophy\n\n### Evaluation Checklist\n\nWhen reviewing any system design, run it through these lenses:\n\n| Principle | Question | Red Flag |\n|---|---|---|\n| Mechanism vs Policy | Can two users want different behavior here? | Policy hardcoded in the mechanism layer |\n| Do One Thing Well | Can you describe this component's job in one sentence? | \"It handles X and also Y and sometimes Z\" |\n| Text Streams | What's the universal interchange format? | Every integration requires a bespoke adapter |\n| Composability | Can this be used in a way the designer didn't anticipate? | Component only works in one specific workflow |\n| Convention Over Configuration | What's the zero-config experience? | User must configure 12 settings before first use |\n| Silence is Golden | What does a healthy system's log look like? | Pages of output with no errors to be found |\n| Everything is a File | What's the uniform interface? | Every entity type has a completely different API |\n\n### Where the Philosophy Applies Well\n\n- **Tools and libraries.** The Unix philosophy was designed for tools. Components that are called by other software, that need to compose, that serve diverse use cases — this is where these principles shine.\n- **Infrastructure and platforms.** Mechanism vs policy is the essential question for any platform. Convention over configuration determines whether the platform is adoptable. Composability determines whether it scales to unforeseen use cases.\n- **APIs and integration layers.** Universal interfaces, silent success, and composability directly determine API quality.\n- **Developer experience.** Conventions, least surprise, and sensible defaults are the difference between a tool developers love and a tool developers tolerate.\n\n### Where the Philosophy Applies Poorly\n\n- **End-user applications.** Users want a cohesive experience, not a bag of composable parts. An email client that requires piping five tools together is not a better email client. The composition should happen *beneath* the product surface.\n- **UI-heavy products.** \"Silence is golden\" is wrong for user interfaces. Users need feedback: loading spinners, success toasts, progress indicators. The interface is the policy layer — it *should* be opinionated.\n- **Safety-critical systems.** \"Everything is a file\" uniformity can obscure critical distinctions. When deleting a configuration file and deleting a production database use the same interface, uniformity works against you. Sometimes different things should *feel* different.\n- **Exploratory\u002Fcreative domains.** \"Do one thing well\" assumes you know what the things are. In novel domains, the responsibility boundaries aren't clear yet. Premature decomposition creates arbitrary boundaries that must be redrawn as understanding deepens.\n\n### The Meta-Principle\n\nThe Unix philosophy is, itself, a mechanism — not a policy. It provides *thinking tools* for evaluating designs, not *rules* for making them. The judgment of when to apply each principle, how strongly, and when to deliberately violate one in service of another — that's the policy, and it's yours to make.\n",{"data":37,"body":38},{"name":4,"description":6},{"type":39,"children":40},"root",[41,50,56,60,67,87,104,112,147,155,173,183,186,192,236,244,270,287,311,318,336,353,356,362,367,375,387,395,536,544,577,584,602,605,611,620,630,638,650,658,717,727,734,752,768,771,777,838,846,883,891,924,932,1006,1014,1019,1053,1060,1078,1081,1087,1100,1110,1118,1229,1237,1256,1269,1276,1294,1297,1303,1353,1361,1366,1373,1491,1499,1540,1548,1553,1560,1578,1581,1587,1594,1599,1747,1753,1796,1802,1866,1872],{"type":42,"tag":43,"props":44,"children":46},"element","h1",{"id":45},"design-philosophy-unixlinux",[47],{"type":48,"value":49},"text","Design Philosophy: Unix\u002FLinux",{"type":42,"tag":51,"props":52,"children":53},"p",{},[54],{"type":48,"value":55},"The Unix philosophy as a thinking tool for modern system design.",{"type":42,"tag":57,"props":58,"children":59},"hr",{},[],{"type":42,"tag":61,"props":62,"children":64},"h2",{"id":63},"mechanism-vs-policy",[65],{"type":48,"value":66},"Mechanism vs Policy",{"type":42,"tag":51,"props":68,"children":69},{},[70,72,78,80,85],{"type":48,"value":71},"The deepest principle in Unix. The kernel provides ",{"type":42,"tag":73,"props":74,"children":75},"em",{},[76],{"type":48,"value":77},"mechanisms",{"type":48,"value":79}," (process scheduling, file descriptors, memory mapping). User-space provides ",{"type":42,"tag":73,"props":81,"children":82},{},[83],{"type":48,"value":84},"policy",{"type":48,"value":86}," (which processes run, what files mean, how memory is used). The kernel doesn't have opinions about your workflow. It gives you the tools to build any workflow.",{"type":42,"tag":51,"props":88,"children":89},{},[90,96,98,102],{"type":42,"tag":91,"props":92,"children":93},"strong",{},[94],{"type":48,"value":95},"The litmus test:",{"type":48,"value":97}," Could two reasonable users want different behavior here? If yes, you're looking at ",{"type":42,"tag":73,"props":99,"children":100},{},[101],{"type":48,"value":84},{"type":48,"value":103}," — don't hardcode it. Provide a mechanism and let the caller decide.",{"type":42,"tag":51,"props":105,"children":106},{},[107],{"type":42,"tag":91,"props":108,"children":109},{},[110],{"type":48,"value":111},"How this applies broadly:",{"type":42,"tag":113,"props":114,"children":115},"ul",{},[116,127,137],{"type":42,"tag":117,"props":118,"children":119},"li",{},[120,125],{"type":42,"tag":91,"props":121,"children":122},{},[123],{"type":48,"value":124},"Frameworks provide mechanisms; applications provide policy.",{"type":48,"value":126}," A web framework gives you routing, middleware, and request handling. It should not decide your authentication strategy, your URL naming conventions, or your error page content. When a framework makes policy decisions for you, it works until your policy diverges — then you fight the framework.",{"type":42,"tag":117,"props":128,"children":129},{},[130,135],{"type":42,"tag":91,"props":131,"children":132},{},[133],{"type":48,"value":134},"Libraries vs. frameworks",{"type":48,"value":136}," is often a mechanism-vs-policy question. A library gives you mechanisms you call. A framework calls your code within its policy structure. Prefer libraries when the domain is well-understood and teams have strong opinions. Prefer frameworks when teams need guardrails and the policy is genuinely standard.",{"type":42,"tag":117,"props":138,"children":139},{},[140,145],{"type":42,"tag":91,"props":141,"children":142},{},[143],{"type":48,"value":144},"Configuration systems",{"type":48,"value":146}," should separate mechanism (how config is loaded, merged, validated) from policy (what the config values mean, what defaults are appropriate). The mechanism should be boring. The policy is the interesting part.",{"type":42,"tag":51,"props":148,"children":149},{},[150],{"type":42,"tag":91,"props":151,"children":152},{},[153],{"type":48,"value":154},"Design evaluation questions:",{"type":42,"tag":113,"props":156,"children":157},{},[158,163,168],{"type":42,"tag":117,"props":159,"children":160},{},[161],{"type":48,"value":162},"Where in this design are mechanism and policy entangled? Can they be separated?",{"type":42,"tag":117,"props":164,"children":165},{},[166],{"type":48,"value":167},"When this system's users inevitably want different behavior, which parts will they need to fork vs. configure?",{"type":42,"tag":117,"props":169,"children":170},{},[171],{"type":48,"value":172},"Are we embedding today's policy decisions into tomorrow's mechanism layer?",{"type":42,"tag":51,"props":174,"children":175},{},[176,181],{"type":42,"tag":91,"props":177,"children":178},{},[179],{"type":48,"value":180},"The failure mode:",{"type":48,"value":182}," Over-separating mechanism from policy creates systems that are infinitely flexible and impossible to use out of the box. X11 separated mechanism from policy so aggressively that every desktop environment had to reinvent window management from scratch. The mechanism layer should be opinionated enough to be useful — just not so opinionated that it precludes valid alternatives.",{"type":42,"tag":57,"props":184,"children":185},{},[],{"type":42,"tag":61,"props":187,"children":189},{"id":188},"do-one-thing-well",[190],{"type":48,"value":191},"Do One Thing Well",{"type":42,"tag":51,"props":193,"children":194},{},[195,197,204,206,212,214,220,222,227,229,234],{"type":48,"value":196},"The most cited and most misunderstood Unix principle. ",{"type":42,"tag":198,"props":199,"children":201},"code",{"className":200},[],[202],{"type":48,"value":203},"grep",{"type":48,"value":205}," searches. ",{"type":42,"tag":198,"props":207,"children":209},{"className":208},[],[210],{"type":48,"value":211},"sort",{"type":48,"value":213}," sorts. ",{"type":42,"tag":198,"props":215,"children":217},{"className":216},[],[218],{"type":48,"value":219},"uniq",{"type":48,"value":221}," deduplicates. Each does one thing, does it thoroughly, and handles edge cases within its domain. The key word is ",{"type":42,"tag":73,"props":223,"children":224},{},[225],{"type":48,"value":226},"well",{"type":48,"value":228},", not ",{"type":42,"tag":73,"props":230,"children":231},{},[232],{"type":48,"value":233},"small",{"type":48,"value":235},".",{"type":42,"tag":51,"props":237,"children":238},{},[239],{"type":42,"tag":91,"props":240,"children":241},{},[242],{"type":48,"value":243},"What this actually means:",{"type":42,"tag":51,"props":245,"children":246},{},[247,249,254,256,261,263,268],{"type":48,"value":248},"A component should have a ",{"type":42,"tag":73,"props":250,"children":251},{},[252],{"type":48,"value":253},"clear responsibility boundary",{"type":48,"value":255},". Everything inside that boundary, it handles completely. Everything outside, it delegates. ",{"type":42,"tag":198,"props":257,"children":259},{"className":258},[],[260],{"type":48,"value":203},{"type":48,"value":262}," doesn't sort its output because sorting is outside its boundary. But ",{"type":42,"tag":198,"props":264,"children":266},{"className":265},[],[267],{"type":48,"value":203},{"type":48,"value":269}," handles binary files, compressed input, recursive directories, regex dialects, and colorized output — because those are all within \"searching text.\"",{"type":42,"tag":51,"props":271,"children":272},{},[273,278,280,285],{"type":42,"tag":91,"props":274,"children":275},{},[276],{"type":48,"value":277},"How microservices got this wrong:",{"type":48,"value":279}," \"Do one thing\" was interpreted as \"be small.\" Teams created services so thin they couldn't do anything useful alone. A \"user service\" that only stores user records but can't validate an email address. A \"notification service\" that can't template a message. The result: every operation requires orchestrating five services, and the ",{"type":42,"tag":73,"props":281,"children":282},{},[283],{"type":48,"value":284},"real",{"type":48,"value":286}," logic lives in the orchestration layer — which is now doing everything and doing it badly.",{"type":42,"tag":51,"props":288,"children":289},{},[290,295,297,302,304,309],{"type":42,"tag":91,"props":291,"children":292},{},[293],{"type":48,"value":294},"The real principle:",{"type":48,"value":296}," Draw clear responsibility boundaries. A component owns a ",{"type":42,"tag":73,"props":298,"children":299},{},[300],{"type":48,"value":301},"coherent",{"type":48,"value":303}," piece of functionality, not a ",{"type":42,"tag":73,"props":305,"children":306},{},[307],{"type":48,"value":308},"minimal",{"type":48,"value":310}," piece. The question isn't \"Is this small enough?\" but \"If I need to change how X works, do I change exactly one component?\"",{"type":42,"tag":51,"props":312,"children":313},{},[314],{"type":42,"tag":91,"props":315,"children":316},{},[317],{"type":48,"value":154},{"type":42,"tag":113,"props":319,"children":320},{},[321,326,331],{"type":42,"tag":117,"props":322,"children":323},{},[324],{"type":48,"value":325},"Can you describe what this component does in one sentence without using \"and\"?",{"type":42,"tag":117,"props":327,"children":328},{},[329],{"type":48,"value":330},"If the requirements for this responsibility change, how many components must change?",{"type":42,"tag":117,"props":332,"children":333},{},[334],{"type":48,"value":335},"Is this component thin because its responsibility is naturally narrow, or because we artificially split a coherent responsibility?",{"type":42,"tag":51,"props":337,"children":338},{},[339,344,346,351],{"type":42,"tag":91,"props":340,"children":341},{},[342],{"type":48,"value":343},"The tension:",{"type":48,"value":345}," \"Do one thing well\" is in tension with \"provide a complete solution.\" Unix resolves this through composition — the ",{"type":42,"tag":73,"props":347,"children":348},{},[349],{"type":48,"value":350},"pipeline",{"type":48,"value":352}," provides the complete solution while each tool provides one step. Your system needs an equivalent composition mechanism. If you don't have one, making components smaller just makes the system harder to use.",{"type":42,"tag":57,"props":354,"children":355},{},[],{"type":42,"tag":61,"props":357,"children":359},{"id":358},"text-streams-as-universal-interface",[360],{"type":48,"value":361},"Text Streams as Universal Interface",{"type":42,"tag":51,"props":363,"children":364},{},[365],{"type":48,"value":366},"Unix programs communicate through text streams. The format is simple enough that any program can produce and consume it. This means any program can connect to any other program, even programs that were written decades apart by people who never met.",{"type":42,"tag":51,"props":368,"children":369},{},[370],{"type":42,"tag":91,"props":371,"children":372},{},[373],{"type":48,"value":374},"The power of a universal interchange format:",{"type":42,"tag":51,"props":376,"children":377},{},[378,380,385],{"type":48,"value":379},"The magic isn't text. The magic is ",{"type":42,"tag":73,"props":381,"children":382},{},[383],{"type":48,"value":384},"universality",{"type":48,"value":386},". When every component speaks the same format, the number of possible integrations is N (one adapter per component), not N² (one adapter per pair). You pay for this with type safety — text streams carry no schema, no types, no validation. That's the trade.",{"type":42,"tag":51,"props":388,"children":389},{},[390],{"type":42,"tag":91,"props":391,"children":392},{},[393],{"type":48,"value":394},"How this maps to modern systems:",{"type":42,"tag":396,"props":397,"children":398},"table",{},[399,423],{"type":42,"tag":400,"props":401,"children":402},"thead",{},[403],{"type":42,"tag":404,"props":405,"children":406},"tr",{},[407,413,418],{"type":42,"tag":408,"props":409,"children":410},"th",{},[411],{"type":48,"value":412},"Unix Concept",{"type":42,"tag":408,"props":414,"children":415},{},[416],{"type":48,"value":417},"Modern Equivalent",{"type":42,"tag":408,"props":419,"children":420},{},[421],{"type":48,"value":422},"Tradeoff",{"type":42,"tag":424,"props":425,"children":426},"tbody",{},[427,446,464,482,500,518],{"type":42,"tag":404,"props":428,"children":429},{},[430,436,441],{"type":42,"tag":431,"props":432,"children":433},"td",{},[434],{"type":48,"value":435},"Text streams",{"type":42,"tag":431,"props":437,"children":438},{},[439],{"type":48,"value":440},"JSON payloads",{"type":42,"tag":431,"props":442,"children":443},{},[444],{"type":48,"value":445},"Human-readable, schema-optional, verbose",{"type":42,"tag":404,"props":447,"children":448},{},[449,454,459],{"type":42,"tag":431,"props":450,"children":451},{},[452],{"type":48,"value":453},"Pipes",{"type":42,"tag":431,"props":455,"children":456},{},[457],{"type":48,"value":458},"HTTP requests",{"type":42,"tag":431,"props":460,"children":461},{},[462],{"type":48,"value":463},"Universal, stateless, high overhead per call",{"type":42,"tag":404,"props":465,"children":466},{},[467,472,477],{"type":42,"tag":431,"props":468,"children":469},{},[470],{"type":48,"value":471},"Signals",{"type":42,"tag":431,"props":473,"children":474},{},[475],{"type":48,"value":476},"Events\u002Fwebhooks",{"type":42,"tag":431,"props":478,"children":479},{},[480],{"type":48,"value":481},"Async notification, no return value",{"type":42,"tag":404,"props":483,"children":484},{},[485,490,495],{"type":42,"tag":431,"props":486,"children":487},{},[488],{"type":48,"value":489},"Files",{"type":42,"tag":431,"props":491,"children":492},{},[493],{"type":48,"value":494},"Object storage \u002F REST resources",{"type":42,"tag":431,"props":496,"children":497},{},[498],{"type":48,"value":499},"Addressable, persistent, no push notification",{"type":42,"tag":404,"props":501,"children":502},{},[503,508,513],{"type":42,"tag":431,"props":504,"children":505},{},[506],{"type":48,"value":507},"stdin\u002Fstdout",{"type":42,"tag":431,"props":509,"children":510},{},[511],{"type":48,"value":512},"Request body \u002F response body",{"type":42,"tag":431,"props":514,"children":515},{},[516],{"type":48,"value":517},"Clear directionality, one-shot",{"type":42,"tag":404,"props":519,"children":520},{},[521,526,531],{"type":42,"tag":431,"props":522,"children":523},{},[524],{"type":48,"value":525},"Environment vars",{"type":42,"tag":431,"props":527,"children":528},{},[529],{"type":48,"value":530},"Configuration injection",{"type":42,"tag":431,"props":532,"children":533},{},[534],{"type":48,"value":535},"Implicit, global, stringly-typed",{"type":42,"tag":51,"props":537,"children":538},{},[539],{"type":42,"tag":91,"props":540,"children":541},{},[542],{"type":48,"value":543},"The tradeoff between universal and typed interfaces:",{"type":42,"tag":113,"props":545,"children":546},{},[547,557,567],{"type":42,"tag":117,"props":548,"children":549},{},[550,555],{"type":42,"tag":91,"props":551,"children":552},{},[553],{"type":48,"value":554},"Universal interfaces",{"type":48,"value":556}," (text, JSON, HTTP) are simple to adopt, compose freely, and degrade gracefully. But they're lossy — you can't express \"this field is an ISO-8601 timestamp\" in plain JSON without a schema sidecar.",{"type":42,"tag":117,"props":558,"children":559},{},[560,565],{"type":42,"tag":91,"props":561,"children":562},{},[563],{"type":48,"value":564},"Typed interfaces",{"type":48,"value":566}," (protobuf, gRPC, GraphQL with schemas) are safe, self-documenting, and enable tooling. But they're rigid — every interface change requires coordinated updates, and composition requires adapters.",{"type":42,"tag":117,"props":568,"children":569},{},[570,575],{"type":42,"tag":91,"props":571,"children":572},{},[573],{"type":48,"value":574},"The Unix bias is toward universality.",{"type":48,"value":576}," You can always add validation on top of a universal format. You can't easily add universality on top of a typed format.",{"type":42,"tag":51,"props":578,"children":579},{},[580],{"type":42,"tag":91,"props":581,"children":582},{},[583],{"type":48,"value":154},{"type":42,"tag":113,"props":585,"children":586},{},[587,592,597],{"type":42,"tag":117,"props":588,"children":589},{},[590],{"type":48,"value":591},"What is the \"text stream\" of this system — the universal format everything can speak?",{"type":42,"tag":117,"props":593,"children":594},{},[595],{"type":48,"value":596},"Could a component written by a different team, in a different language, five years from now, connect to this interface without special knowledge?",{"type":42,"tag":117,"props":598,"children":599},{},[600],{"type":48,"value":601},"Are we paying the cost of typed interfaces (coordination, rigidity) and actually getting the benefit (safety, tooling)?",{"type":42,"tag":57,"props":603,"children":604},{},[],{"type":42,"tag":61,"props":606,"children":608},{"id":607},"composability-over-features",[609],{"type":48,"value":610},"Composability Over Features",{"type":42,"tag":51,"props":612,"children":613},{},[614],{"type":42,"tag":198,"props":615,"children":617},{"className":616},[],[618],{"type":48,"value":619},"cat access.log | grep 404 | cut -d' ' -f7 | sort | uniq -c | sort -rn | head -20",{"type":42,"tag":51,"props":621,"children":622},{},[623,625],{"type":48,"value":624},"Nobody designed a \"top 20 not-found URLs\" feature. The feature emerged from composition. This is the central insight: ",{"type":42,"tag":91,"props":626,"children":627},{},[628],{"type":48,"value":629},"composable systems gain features over time without changing existing components.",{"type":42,"tag":51,"props":631,"children":632},{},[633],{"type":42,"tag":91,"props":634,"children":635},{},[636],{"type":48,"value":637},"Stdin\u002Fstdout discipline:",{"type":42,"tag":51,"props":639,"children":640},{},[641,643,648],{"type":48,"value":642},"What makes Unix tools composable isn't their size — it's their ",{"type":42,"tag":73,"props":644,"children":645},{},[646],{"type":48,"value":647},"discipline",{"type":48,"value":649},". Each tool reads from stdin, writes to stdout, and reports errors to stderr. This discipline is what enables arbitrary connection. Without it, composition is accidental at best.",{"type":42,"tag":51,"props":651,"children":652},{},[653],{"type":42,"tag":91,"props":654,"children":655},{},[656],{"type":48,"value":657},"The equivalent disciplines for modern systems:",{"type":42,"tag":113,"props":659,"children":660},{},[661,671,697,707],{"type":42,"tag":117,"props":662,"children":663},{},[664,669],{"type":42,"tag":91,"props":665,"children":666},{},[667],{"type":48,"value":668},"API design:",{"type":48,"value":670}," Accept the common format. Return the common format. Don't require callers to know your internal model. REST APIs that accept JSON and return JSON compose. APIs that require bespoke SDKs don't.",{"type":42,"tag":117,"props":672,"children":673},{},[674,679,681,687,689,695],{"type":42,"tag":91,"props":675,"children":676},{},[677],{"type":48,"value":678},"Event systems:",{"type":48,"value":680}," Emit events that describe what happened, not what the listener should do. ",{"type":42,"tag":198,"props":682,"children":684},{"className":683},[],[685],{"type":48,"value":686},"OrderPlaced { orderId, items, total }",{"type":48,"value":688}," composes. ",{"type":42,"tag":198,"props":690,"children":692},{"className":691},[],[693],{"type":48,"value":694},"SendConfirmationEmail { to, template }",{"type":48,"value":696}," doesn't — it embeds policy in the event.",{"type":42,"tag":117,"props":698,"children":699},{},[700,705],{"type":42,"tag":91,"props":701,"children":702},{},[703],{"type":48,"value":704},"Plugin architectures:",{"type":48,"value":706}," Define a minimal interface. Accept any implementation. The plugin boundary is the \"pipe\" — the more assumptions it carries, the fewer plugins are possible.",{"type":42,"tag":117,"props":708,"children":709},{},[710,715],{"type":42,"tag":91,"props":711,"children":712},{},[713],{"type":48,"value":714},"Data pipelines:",{"type":48,"value":716}," Transform data, emit data. Don't hold state between records unless the transformation requires it. Stateless transforms compose arbitrarily. Stateful ones require careful ordering.",{"type":42,"tag":51,"props":718,"children":719},{},[720,725],{"type":42,"tag":91,"props":721,"children":722},{},[723],{"type":48,"value":724},"The composability test:",{"type":48,"value":726}," Can someone use this in a way I didn't anticipate? If your component can only be used in the one workflow you designed it for, it's not composable — it's a step in a procedure.",{"type":42,"tag":51,"props":728,"children":729},{},[730],{"type":42,"tag":91,"props":731,"children":732},{},[733],{"type":48,"value":154},{"type":42,"tag":113,"props":735,"children":736},{},[737,742,747],{"type":42,"tag":117,"props":738,"children":739},{},[740],{"type":48,"value":741},"If I remove this component from the pipeline, can I replace it with something else that speaks the same interface?",{"type":42,"tag":117,"props":743,"children":744},{},[745],{"type":48,"value":746},"Does this component pull its dependencies, or are dependencies pushed to it?",{"type":42,"tag":117,"props":748,"children":749},{},[750],{"type":48,"value":751},"Could a user pipe the output of this into something I've never heard of?",{"type":42,"tag":51,"props":753,"children":754},{},[755,759,761,766],{"type":42,"tag":91,"props":756,"children":757},{},[758],{"type":48,"value":180},{"type":48,"value":760}," Composability fetishism. Not everything needs to compose. A user-facing application is a ",{"type":42,"tag":73,"props":762,"children":763},{},[764],{"type":48,"value":765},"composition",{"type":48,"value":767}," — it should present a cohesive experience, not expose its internal pipes. Compose at the infrastructure layer. Integrate at the product layer.",{"type":42,"tag":57,"props":769,"children":770},{},[],{"type":42,"tag":61,"props":772,"children":774},{"id":773},"convention-over-configuration",[775],{"type":48,"value":776},"Convention Over Configuration",{"type":42,"tag":51,"props":778,"children":779},{},[780,782,788,790,796,798,804,806,812,814,820,822,828,830,836],{"type":48,"value":781},"Unix is full of conventions. Config lives in ",{"type":42,"tag":198,"props":783,"children":785},{"className":784},[],[786],{"type":48,"value":787},"\u002Fetc",{"type":48,"value":789},". User config lives in ",{"type":42,"tag":198,"props":791,"children":793},{"className":792},[],[794],{"type":48,"value":795},"~\u002F.config",{"type":48,"value":797}," (XDG) or ",{"type":42,"tag":198,"props":799,"children":801},{"className":800},[],[802],{"type":48,"value":803},"~\u002F.\u003Capp>",{"type":48,"value":805},". Executables live in ",{"type":42,"tag":198,"props":807,"children":809},{"className":808},[],[810],{"type":48,"value":811},"\u002Fusr\u002Fbin",{"type":48,"value":813}," or ",{"type":42,"tag":198,"props":815,"children":817},{"className":816},[],[818],{"type":48,"value":819},"\u002Fusr\u002Flocal\u002Fbin",{"type":48,"value":821},". Logs go to ",{"type":42,"tag":198,"props":823,"children":825},{"className":824},[],[826],{"type":48,"value":827},"\u002Fvar\u002Flog",{"type":48,"value":829},". Temp files go to ",{"type":42,"tag":198,"props":831,"children":833},{"className":832},[],[834],{"type":48,"value":835},"\u002Ftmp",{"type":48,"value":837},". None of this is enforced by the kernel — it's pure convention. And it works because everyone follows it.",{"type":42,"tag":51,"props":839,"children":840},{},[841],{"type":42,"tag":91,"props":842,"children":843},{},[844],{"type":48,"value":845},"Why conventions reduce cognitive load:",{"type":42,"tag":51,"props":847,"children":848},{},[849,851,857,859,865,867,873,875,881],{"type":48,"value":850},"Every decision a user doesn't have to make is cognitive budget freed for the decisions that matter. When you ",{"type":42,"tag":198,"props":852,"children":854},{"className":853},[],[855],{"type":48,"value":856},"apt install nginx",{"type":48,"value":858},", you know the config is in ",{"type":42,"tag":198,"props":860,"children":862},{"className":861},[],[863],{"type":48,"value":864},"\u002Fetc\u002Fnginx\u002F",{"type":48,"value":866},", the logs are in ",{"type":42,"tag":198,"props":868,"children":870},{"className":869},[],[871],{"type":48,"value":872},"\u002Fvar\u002Flog\u002Fnginx\u002F",{"type":48,"value":874},", and the binary is in ",{"type":42,"tag":198,"props":876,"children":878},{"className":877},[],[879],{"type":48,"value":880},"\u002Fusr\u002Fsbin\u002F",{"type":48,"value":882},". You didn't read the docs to learn this. You just knew, because convention.",{"type":42,"tag":51,"props":884,"children":885},{},[886],{"type":42,"tag":91,"props":887,"children":888},{},[889],{"type":48,"value":890},"The 80\u002F20 rule of configuration:",{"type":42,"tag":113,"props":892,"children":893},{},[894,904,914],{"type":42,"tag":117,"props":895,"children":896},{},[897,902],{"type":42,"tag":91,"props":898,"children":899},{},[900],{"type":48,"value":901},"The common case should require zero configuration.",{"type":48,"value":903}," Sensible defaults that work for 80% of users.",{"type":42,"tag":117,"props":905,"children":906},{},[907,912],{"type":42,"tag":91,"props":908,"children":909},{},[910],{"type":48,"value":911},"The uncommon case should be configurable, not impossible.",{"type":48,"value":913}," Flags, config files, environment variables — progressive disclosure of complexity.",{"type":42,"tag":117,"props":915,"children":916},{},[917,922],{"type":42,"tag":91,"props":918,"children":919},{},[920],{"type":48,"value":921},"The rare case can require code.",{"type":48,"value":923}," Plugins, extensions, custom builds. It's okay if the 1% case is hard.",{"type":42,"tag":51,"props":925,"children":926},{},[927],{"type":42,"tag":91,"props":928,"children":929},{},[930],{"type":48,"value":931},"How this maps to system design:",{"type":42,"tag":113,"props":933,"children":934},{},[935,945,978,996],{"type":42,"tag":117,"props":936,"children":937},{},[938,943],{"type":42,"tag":91,"props":939,"children":940},{},[941],{"type":48,"value":942},"Directory\u002Ffile structure:",{"type":48,"value":944}," Establish conventions early. Where do configs go? Where do logs go? Where do plugins go? Document it once, then rely on it everywhere.",{"type":42,"tag":117,"props":946,"children":947},{},[948,953,955,961,963,969,970,976],{"type":42,"tag":91,"props":949,"children":950},{},[951],{"type":48,"value":952},"Naming conventions:",{"type":48,"value":954}," ",{"type":42,"tag":198,"props":956,"children":958},{"className":957},[],[959],{"type":48,"value":960},"GET \u002Fusers",{"type":48,"value":962},", ",{"type":42,"tag":198,"props":964,"children":966},{"className":965},[],[967],{"type":48,"value":968},"POST \u002Fusers",{"type":48,"value":962},{"type":42,"tag":198,"props":971,"children":973},{"className":972},[],[974],{"type":48,"value":975},"GET \u002Fusers\u002F:id",{"type":48,"value":977},". REST naming conventions mean you can often guess an API without reading docs.",{"type":42,"tag":117,"props":979,"children":980},{},[981,986,988,994],{"type":42,"tag":91,"props":982,"children":983},{},[984],{"type":48,"value":985},"Error formats:",{"type":48,"value":987}," One error format for the whole system. ",{"type":42,"tag":198,"props":989,"children":991},{"className":990},[],[992],{"type":48,"value":993},"{ \"error\": { \"code\": \"NOT_FOUND\", \"message\": \"...\" } }",{"type":48,"value":995},". Don't make callers handle five different error shapes.",{"type":42,"tag":117,"props":997,"children":998},{},[999,1004],{"type":42,"tag":91,"props":1000,"children":1001},{},[1002],{"type":48,"value":1003},"Configuration hierarchy:",{"type":48,"value":1005}," CLI flags override environment variables override config files override defaults. This isn't arbitrary — it's a convention that every Unix tool follows, and your users expect it.",{"type":42,"tag":51,"props":1007,"children":1008},{},[1009],{"type":42,"tag":91,"props":1010,"children":1011},{},[1012],{"type":48,"value":1013},"The failure mode: invisible assumptions.",{"type":42,"tag":51,"props":1015,"children":1016},{},[1017],{"type":48,"value":1018},"When conventions become so ingrained that nobody documents them, they become invisible assumptions. New team members violate them without knowing they exist. The convention calcifies into a trap. Conventions must be:",{"type":42,"tag":1020,"props":1021,"children":1022},"ol",{},[1023,1033,1043],{"type":42,"tag":117,"props":1024,"children":1025},{},[1026,1031],{"type":42,"tag":91,"props":1027,"children":1028},{},[1029],{"type":48,"value":1030},"Documented",{"type":48,"value":1032}," — in a place people actually look.",{"type":42,"tag":117,"props":1034,"children":1035},{},[1036,1041],{"type":42,"tag":91,"props":1037,"children":1038},{},[1039],{"type":48,"value":1040},"Enforced",{"type":48,"value":1042}," — by linters, tests, or at minimum code review.",{"type":42,"tag":117,"props":1044,"children":1045},{},[1046,1051],{"type":42,"tag":91,"props":1047,"children":1048},{},[1049],{"type":48,"value":1050},"Discoverable",{"type":48,"value":1052}," — a new developer should be able to find them within their first day.",{"type":42,"tag":51,"props":1054,"children":1055},{},[1056],{"type":42,"tag":91,"props":1057,"children":1058},{},[1059],{"type":48,"value":154},{"type":42,"tag":113,"props":1061,"children":1062},{},[1063,1068,1073],{"type":42,"tag":117,"props":1064,"children":1065},{},[1066],{"type":48,"value":1067},"What would a reasonable default be for this setting? Is there any reason not to use it?",{"type":42,"tag":117,"props":1069,"children":1070},{},[1071],{"type":48,"value":1072},"How many configuration options does this system have? For each one, what percentage of users will ever change it?",{"type":42,"tag":117,"props":1074,"children":1075},{},[1076],{"type":48,"value":1077},"If a new developer joins, how long until they can predict where things are without asking?",{"type":42,"tag":57,"props":1079,"children":1080},{},[],{"type":42,"tag":61,"props":1082,"children":1084},{"id":1083},"silence-is-golden",[1085],{"type":48,"value":1086},"Silence is Golden",{"type":42,"tag":51,"props":1088,"children":1089},{},[1090,1092,1098],{"type":48,"value":1091},"Run ",{"type":42,"tag":198,"props":1093,"children":1095},{"className":1094},[],[1096],{"type":48,"value":1097},"cp file1 file2",{"type":48,"value":1099},". If it succeeds, it prints nothing. You only hear from it if something goes wrong. This isn't laziness — it's design. Silent success means the output stream carries only signal. If every command printed \"Success!\", pipelines would drown in noise.",{"type":42,"tag":51,"props":1101,"children":1102},{},[1103,1108],{"type":42,"tag":91,"props":1104,"children":1105},{},[1106],{"type":48,"value":1107},"The principle:",{"type":48,"value":1109}," Don't produce output unless you have something the user didn't already know. Success is expected — don't announce it. Failure is unexpected — report it clearly.",{"type":42,"tag":51,"props":1111,"children":1112},{},[1113],{"type":42,"tag":91,"props":1114,"children":1115},{},[1116],{"type":48,"value":1117},"How this applies to modern systems:",{"type":42,"tag":113,"props":1119,"children":1120},{},[1121,1138,1164,1195],{"type":42,"tag":117,"props":1122,"children":1123},{},[1124,1129,1131,1136],{"type":42,"tag":91,"props":1125,"children":1126},{},[1127],{"type":48,"value":1128},"Logging levels exist for a reason.",{"type":48,"value":1130}," If your service logs every successful request at INFO level, you've made INFO useless. Log the ",{"type":42,"tag":73,"props":1132,"children":1133},{},[1134],{"type":48,"value":1135},"surprising",{"type":48,"value":1137}," things: the request that took 10x longer than usual, the retry that succeeded on the third attempt, the config value that was overridden. DEBUG is for \"I'm actively investigating.\" INFO is for \"an operator should see this over time.\" WARN is for \"something is degraded.\" ERROR is for \"something is broken.\"",{"type":42,"tag":117,"props":1139,"children":1140},{},[1141,1146,1148,1154,1156,1162],{"type":42,"tag":91,"props":1142,"children":1143},{},[1144],{"type":48,"value":1145},"API responses:",{"type":48,"value":1147}," A ",{"type":42,"tag":198,"props":1149,"children":1151},{"className":1150},[],[1152],{"type":48,"value":1153},"204 No Content",{"type":48,"value":1155}," is the Unix-philosophy response to a successful DELETE. The status code tells you it worked. An empty body tells you there's nothing more to say. Don't wrap every response in ",{"type":42,"tag":198,"props":1157,"children":1159},{"className":1158},[],[1160],{"type":48,"value":1161},"{ \"status\": \"success\", \"message\": \"Operation completed successfully\" }",{"type":48,"value":1163}," — that's noise masquerading as helpfulness.",{"type":42,"tag":117,"props":1165,"children":1166},{},[1167,1172,1174,1179,1181,1186,1188,1193],{"type":42,"tag":91,"props":1168,"children":1169},{},[1170],{"type":48,"value":1171},"Error handling:",{"type":48,"value":1173}," When something fails, say ",{"type":42,"tag":73,"props":1175,"children":1176},{},[1177],{"type":48,"value":1178},"what",{"type":48,"value":1180}," failed, ",{"type":42,"tag":73,"props":1182,"children":1183},{},[1184],{"type":48,"value":1185},"why",{"type":48,"value":1187}," it failed, and ",{"type":42,"tag":73,"props":1189,"children":1190},{},[1191],{"type":48,"value":1192},"what the user can do about it",{"type":48,"value":1194},". Don't say \"An error occurred.\" That's the error-handling equivalent of printing \"Success!\" on every operation — technically true and completely useless.",{"type":42,"tag":117,"props":1196,"children":1197},{},[1198,1203,1205,1211,1213,1219,1221,1227],{"type":42,"tag":91,"props":1199,"children":1200},{},[1201],{"type":48,"value":1202},"CLI output:",{"type":48,"value":1204}," Default to quiet. Add ",{"type":42,"tag":198,"props":1206,"children":1208},{"className":1207},[],[1209],{"type":48,"value":1210},"-v",{"type":48,"value":1212}," for verbose. Add ",{"type":42,"tag":198,"props":1214,"children":1216},{"className":1215},[],[1217],{"type":48,"value":1218},"-vv",{"type":48,"value":1220}," for debug. Never make the user pipe through ",{"type":42,"tag":198,"props":1222,"children":1224},{"className":1223},[],[1225],{"type":48,"value":1226},"grep -v",{"type":48,"value":1228}," to find the actual output.",{"type":42,"tag":51,"props":1230,"children":1231},{},[1232],{"type":42,"tag":91,"props":1233,"children":1234},{},[1235],{"type":48,"value":1236},"The principle of least surprise:",{"type":42,"tag":51,"props":1238,"children":1239},{},[1240,1242,1248,1250,1255],{"type":48,"value":1241},"Related but distinct: the system should behave the way the user expects. If a function is called ",{"type":42,"tag":198,"props":1243,"children":1245},{"className":1244},[],[1246],{"type":48,"value":1247},"delete()",{"type":48,"value":1249},", it should delete — not archive, not soft-delete, not mark-for-deletion. If it does something other than delete, call it something other than ",{"type":42,"tag":198,"props":1251,"children":1253},{"className":1252},[],[1254],{"type":48,"value":1247},{"type":48,"value":235},{"type":42,"tag":51,"props":1257,"children":1258},{},[1259,1261,1267],{"type":48,"value":1260},"Least surprise is evaluated from the user's perspective, not the implementer's. What a user expects depends on their experience and the conventions of the domain. A Unix user expects ",{"type":42,"tag":198,"props":1262,"children":1264},{"className":1263},[],[1265],{"type":48,"value":1266},"rm",{"type":48,"value":1268}," to be permanent. A Google Docs user expects delete to be recoverable. Neither is wrong — but surprising the user is always wrong.",{"type":42,"tag":51,"props":1270,"children":1271},{},[1272],{"type":42,"tag":91,"props":1273,"children":1274},{},[1275],{"type":48,"value":154},{"type":42,"tag":113,"props":1277,"children":1278},{},[1279,1284,1289],{"type":42,"tag":117,"props":1280,"children":1281},{},[1282],{"type":48,"value":1283},"If this operation succeeds, does the user need to be told? Or can they infer it from context?",{"type":42,"tag":117,"props":1285,"children":1286},{},[1287],{"type":48,"value":1288},"What does this function\u002Fendpoint\u002Fcommand name imply to someone who hasn't read the docs?",{"type":42,"tag":117,"props":1290,"children":1291},{},[1292],{"type":48,"value":1293},"If I read the logs from a healthy system running for a week, how much of it is noise?",{"type":42,"tag":57,"props":1295,"children":1296},{},[],{"type":42,"tag":61,"props":1298,"children":1300},{"id":1299},"everything-is-a-file",[1301],{"type":48,"value":1302},"Everything is a File",{"type":42,"tag":51,"props":1304,"children":1305},{},[1306,1308,1314,1316,1322,1324,1330,1331,1337,1338,1344,1345,1351],{"type":48,"value":1307},"In Unix, devices are files (",{"type":42,"tag":198,"props":1309,"children":1311},{"className":1310},[],[1312],{"type":48,"value":1313},"\u002Fdev\u002Fsda",{"type":48,"value":1315},"), processes are files (",{"type":42,"tag":198,"props":1317,"children":1319},{"className":1318},[],[1320],{"type":48,"value":1321},"\u002Fproc\u002F1234",{"type":48,"value":1323},"), network sockets are files, pipes are files. You interact with all of them using the same system calls: ",{"type":42,"tag":198,"props":1325,"children":1327},{"className":1326},[],[1328],{"type":48,"value":1329},"open",{"type":48,"value":962},{"type":42,"tag":198,"props":1332,"children":1334},{"className":1333},[],[1335],{"type":48,"value":1336},"read",{"type":48,"value":962},{"type":42,"tag":198,"props":1339,"children":1341},{"className":1340},[],[1342],{"type":48,"value":1343},"write",{"type":48,"value":962},{"type":42,"tag":198,"props":1346,"children":1348},{"className":1347},[],[1349],{"type":48,"value":1350},"close",{"type":48,"value":1352},". Learn the file interface once, and you can interact with anything.",{"type":42,"tag":51,"props":1354,"children":1355},{},[1356],{"type":42,"tag":91,"props":1357,"children":1358},{},[1359],{"type":48,"value":1360},"The power of uniform interfaces:",{"type":42,"tag":51,"props":1362,"children":1363},{},[1364],{"type":48,"value":1365},"A uniform interface reduces the API surface area a user must learn. Instead of \"here are 15 different ways to interact with 15 different things,\" it's \"here's one way to interact with everything.\" The user pays a fixed learning cost and gets access to the entire system.",{"type":42,"tag":51,"props":1367,"children":1368},{},[1369],{"type":42,"tag":91,"props":1370,"children":1371},{},[1372],{"type":48,"value":394},{"type":42,"tag":396,"props":1374,"children":1375},{},[1376,1396],{"type":42,"tag":400,"props":1377,"children":1378},{},[1379],{"type":42,"tag":404,"props":1380,"children":1381},{},[1382,1387,1391],{"type":42,"tag":408,"props":1383,"children":1384},{},[1385],{"type":48,"value":1386},"Unix",{"type":42,"tag":408,"props":1388,"children":1389},{},[1390],{"type":48,"value":417},{"type":42,"tag":408,"props":1392,"children":1393},{},[1394],{"type":48,"value":1395},"What's Uniform",{"type":42,"tag":424,"props":1397,"children":1398},{},[1399,1417,1440,1457,1474],{"type":42,"tag":404,"props":1400,"children":1401},{},[1402,1407,1412],{"type":42,"tag":431,"props":1403,"children":1404},{},[1405],{"type":48,"value":1406},"Everything is a file",{"type":42,"tag":431,"props":1408,"children":1409},{},[1410],{"type":48,"value":1411},"REST: everything is a resource",{"type":42,"tag":431,"props":1413,"children":1414},{},[1415],{"type":48,"value":1416},"CRUD operations (GET\u002FPOST\u002FPUT\u002FDELETE)",{"type":42,"tag":404,"props":1418,"children":1419},{},[1420,1424,1429],{"type":42,"tag":431,"props":1421,"children":1422},{},[1423],{"type":48,"value":1406},{"type":42,"tag":431,"props":1425,"children":1426},{},[1427],{"type":48,"value":1428},"Kubernetes: everything is a manifest",{"type":42,"tag":431,"props":1430,"children":1431},{},[1432,1434],{"type":48,"value":1433},"Declare desired state in YAML, ",{"type":42,"tag":198,"props":1435,"children":1437},{"className":1436},[],[1438],{"type":48,"value":1439},"kubectl apply",{"type":42,"tag":404,"props":1441,"children":1442},{},[1443,1447,1452],{"type":42,"tag":431,"props":1444,"children":1445},{},[1446],{"type":48,"value":1406},{"type":42,"tag":431,"props":1448,"children":1449},{},[1450],{"type":48,"value":1451},"Event systems: everything is an event",{"type":42,"tag":431,"props":1453,"children":1454},{},[1455],{"type":48,"value":1456},"Publish, subscribe, replay",{"type":42,"tag":404,"props":1458,"children":1459},{},[1460,1464,1469],{"type":42,"tag":431,"props":1461,"children":1462},{},[1463],{"type":48,"value":1406},{"type":42,"tag":431,"props":1465,"children":1466},{},[1467],{"type":48,"value":1468},"Git: everything is an object",{"type":42,"tag":431,"props":1470,"children":1471},{},[1472],{"type":48,"value":1473},"Hash-addressable, immutable content",{"type":42,"tag":404,"props":1475,"children":1476},{},[1477,1481,1486],{"type":42,"tag":431,"props":1478,"children":1479},{},[1480],{"type":48,"value":1406},{"type":42,"tag":431,"props":1482,"children":1483},{},[1484],{"type":48,"value":1485},"S3: everything is an object",{"type":42,"tag":431,"props":1487,"children":1488},{},[1489],{"type":48,"value":1490},"PUT, GET, DELETE with a key",{"type":42,"tag":51,"props":1492,"children":1493},{},[1494],{"type":42,"tag":91,"props":1495,"children":1496},{},[1497],{"type":48,"value":1498},"The power:",{"type":42,"tag":113,"props":1500,"children":1501},{},[1502,1520,1530],{"type":42,"tag":117,"props":1503,"children":1504},{},[1505,1510,1512,1518],{"type":42,"tag":91,"props":1506,"children":1507},{},[1508],{"type":48,"value":1509},"Tooling compounds.",{"type":48,"value":1511}," Any tool that works with the uniform interface works with everything. ",{"type":42,"tag":198,"props":1513,"children":1515},{"className":1514},[],[1516],{"type":48,"value":1517},"kubectl get",{"type":48,"value":1519}," works on pods, services, deployments, custom resources — anything that speaks the Kubernetes resource interface. One tool, infinite applicability.",{"type":42,"tag":117,"props":1521,"children":1522},{},[1523,1528],{"type":42,"tag":91,"props":1524,"children":1525},{},[1526],{"type":48,"value":1527},"Learning compounds.",{"type":48,"value":1529}," Once you understand the resource model, every new resource type is immediately approachable. You don't start from zero each time.",{"type":42,"tag":117,"props":1531,"children":1532},{},[1533,1538],{"type":42,"tag":91,"props":1534,"children":1535},{},[1536],{"type":48,"value":1537},"Composition is free.",{"type":48,"value":1539}," Components that speak the same interface can be connected without adapters.",{"type":42,"tag":51,"props":1541,"children":1542},{},[1543],{"type":42,"tag":91,"props":1544,"children":1545},{},[1546],{"type":48,"value":1547},"The limits:",{"type":42,"tag":51,"props":1549,"children":1550},{},[1551],{"type":48,"value":1552},"Not everything maps cleanly to one interface. Files have a natural metaphor for \"read this data\" but a strained metaphor for \"subscribe to changes.\" REST has a natural metaphor for CRUD but a strained metaphor for long-running operations, batch processing, or real-time streams. When the uniform interface doesn't fit, you have two bad options: torture the metaphor (POST \u002Forders\u002Fbatch-process-and-notify-async) or break the uniformity (add a WebSocket endpoint alongside REST).",{"type":42,"tag":51,"props":1554,"children":1555},{},[1556],{"type":42,"tag":91,"props":1557,"children":1558},{},[1559],{"type":48,"value":154},{"type":42,"tag":113,"props":1561,"children":1562},{},[1563,1568,1573],{"type":42,"tag":117,"props":1564,"children":1565},{},[1566],{"type":48,"value":1567},"What is the \"file\" in this system — the one abstraction everything maps to?",{"type":42,"tag":117,"props":1569,"children":1570},{},[1571],{"type":48,"value":1572},"Does the uniform interface fit the actual operations, or are we torturing the metaphor?",{"type":42,"tag":117,"props":1574,"children":1575},{},[1576],{"type":48,"value":1577},"What can't be expressed through this interface? Is that acceptable, or does it indicate the wrong abstraction?",{"type":42,"tag":57,"props":1579,"children":1580},{},[],{"type":42,"tag":61,"props":1582,"children":1584},{"id":1583},"applying-the-philosophy",[1585],{"type":48,"value":1586},"Applying the Philosophy",{"type":42,"tag":1588,"props":1589,"children":1591},"h3",{"id":1590},"evaluation-checklist",[1592],{"type":48,"value":1593},"Evaluation Checklist",{"type":42,"tag":51,"props":1595,"children":1596},{},[1597],{"type":48,"value":1598},"When reviewing any system design, run it through these lenses:",{"type":42,"tag":396,"props":1600,"children":1601},{},[1602,1623],{"type":42,"tag":400,"props":1603,"children":1604},{},[1605],{"type":42,"tag":404,"props":1606,"children":1607},{},[1608,1613,1618],{"type":42,"tag":408,"props":1609,"children":1610},{},[1611],{"type":48,"value":1612},"Principle",{"type":42,"tag":408,"props":1614,"children":1615},{},[1616],{"type":48,"value":1617},"Question",{"type":42,"tag":408,"props":1619,"children":1620},{},[1621],{"type":48,"value":1622},"Red Flag",{"type":42,"tag":424,"props":1624,"children":1625},{},[1626,1643,1660,1678,1696,1713,1730],{"type":42,"tag":404,"props":1627,"children":1628},{},[1629,1633,1638],{"type":42,"tag":431,"props":1630,"children":1631},{},[1632],{"type":48,"value":66},{"type":42,"tag":431,"props":1634,"children":1635},{},[1636],{"type":48,"value":1637},"Can two users want different behavior here?",{"type":42,"tag":431,"props":1639,"children":1640},{},[1641],{"type":48,"value":1642},"Policy hardcoded in the mechanism layer",{"type":42,"tag":404,"props":1644,"children":1645},{},[1646,1650,1655],{"type":42,"tag":431,"props":1647,"children":1648},{},[1649],{"type":48,"value":191},{"type":42,"tag":431,"props":1651,"children":1652},{},[1653],{"type":48,"value":1654},"Can you describe this component's job in one sentence?",{"type":42,"tag":431,"props":1656,"children":1657},{},[1658],{"type":48,"value":1659},"\"It handles X and also Y and sometimes Z\"",{"type":42,"tag":404,"props":1661,"children":1662},{},[1663,1668,1673],{"type":42,"tag":431,"props":1664,"children":1665},{},[1666],{"type":48,"value":1667},"Text Streams",{"type":42,"tag":431,"props":1669,"children":1670},{},[1671],{"type":48,"value":1672},"What's the universal interchange format?",{"type":42,"tag":431,"props":1674,"children":1675},{},[1676],{"type":48,"value":1677},"Every integration requires a bespoke adapter",{"type":42,"tag":404,"props":1679,"children":1680},{},[1681,1686,1691],{"type":42,"tag":431,"props":1682,"children":1683},{},[1684],{"type":48,"value":1685},"Composability",{"type":42,"tag":431,"props":1687,"children":1688},{},[1689],{"type":48,"value":1690},"Can this be used in a way the designer didn't anticipate?",{"type":42,"tag":431,"props":1692,"children":1693},{},[1694],{"type":48,"value":1695},"Component only works in one specific workflow",{"type":42,"tag":404,"props":1697,"children":1698},{},[1699,1703,1708],{"type":42,"tag":431,"props":1700,"children":1701},{},[1702],{"type":48,"value":776},{"type":42,"tag":431,"props":1704,"children":1705},{},[1706],{"type":48,"value":1707},"What's the zero-config experience?",{"type":42,"tag":431,"props":1709,"children":1710},{},[1711],{"type":48,"value":1712},"User must configure 12 settings before first use",{"type":42,"tag":404,"props":1714,"children":1715},{},[1716,1720,1725],{"type":42,"tag":431,"props":1717,"children":1718},{},[1719],{"type":48,"value":1086},{"type":42,"tag":431,"props":1721,"children":1722},{},[1723],{"type":48,"value":1724},"What does a healthy system's log look like?",{"type":42,"tag":431,"props":1726,"children":1727},{},[1728],{"type":48,"value":1729},"Pages of output with no errors to be found",{"type":42,"tag":404,"props":1731,"children":1732},{},[1733,1737,1742],{"type":42,"tag":431,"props":1734,"children":1735},{},[1736],{"type":48,"value":1302},{"type":42,"tag":431,"props":1738,"children":1739},{},[1740],{"type":48,"value":1741},"What's the uniform interface?",{"type":42,"tag":431,"props":1743,"children":1744},{},[1745],{"type":48,"value":1746},"Every entity type has a completely different API",{"type":42,"tag":1588,"props":1748,"children":1750},{"id":1749},"where-the-philosophy-applies-well",[1751],{"type":48,"value":1752},"Where the Philosophy Applies Well",{"type":42,"tag":113,"props":1754,"children":1755},{},[1756,1766,1776,1786],{"type":42,"tag":117,"props":1757,"children":1758},{},[1759,1764],{"type":42,"tag":91,"props":1760,"children":1761},{},[1762],{"type":48,"value":1763},"Tools and libraries.",{"type":48,"value":1765}," The Unix philosophy was designed for tools. Components that are called by other software, that need to compose, that serve diverse use cases — this is where these principles shine.",{"type":42,"tag":117,"props":1767,"children":1768},{},[1769,1774],{"type":42,"tag":91,"props":1770,"children":1771},{},[1772],{"type":48,"value":1773},"Infrastructure and platforms.",{"type":48,"value":1775}," Mechanism vs policy is the essential question for any platform. Convention over configuration determines whether the platform is adoptable. Composability determines whether it scales to unforeseen use cases.",{"type":42,"tag":117,"props":1777,"children":1778},{},[1779,1784],{"type":42,"tag":91,"props":1780,"children":1781},{},[1782],{"type":48,"value":1783},"APIs and integration layers.",{"type":48,"value":1785}," Universal interfaces, silent success, and composability directly determine API quality.",{"type":42,"tag":117,"props":1787,"children":1788},{},[1789,1794],{"type":42,"tag":91,"props":1790,"children":1791},{},[1792],{"type":48,"value":1793},"Developer experience.",{"type":48,"value":1795}," Conventions, least surprise, and sensible defaults are the difference between a tool developers love and a tool developers tolerate.",{"type":42,"tag":1588,"props":1797,"children":1799},{"id":1798},"where-the-philosophy-applies-poorly",[1800],{"type":48,"value":1801},"Where the Philosophy Applies Poorly",{"type":42,"tag":113,"props":1803,"children":1804},{},[1805,1822,1839,1856],{"type":42,"tag":117,"props":1806,"children":1807},{},[1808,1813,1815,1820],{"type":42,"tag":91,"props":1809,"children":1810},{},[1811],{"type":48,"value":1812},"End-user applications.",{"type":48,"value":1814}," Users want a cohesive experience, not a bag of composable parts. An email client that requires piping five tools together is not a better email client. The composition should happen ",{"type":42,"tag":73,"props":1816,"children":1817},{},[1818],{"type":48,"value":1819},"beneath",{"type":48,"value":1821}," the product surface.",{"type":42,"tag":117,"props":1823,"children":1824},{},[1825,1830,1832,1837],{"type":42,"tag":91,"props":1826,"children":1827},{},[1828],{"type":48,"value":1829},"UI-heavy products.",{"type":48,"value":1831}," \"Silence is golden\" is wrong for user interfaces. Users need feedback: loading spinners, success toasts, progress indicators. The interface is the policy layer — it ",{"type":42,"tag":73,"props":1833,"children":1834},{},[1835],{"type":48,"value":1836},"should",{"type":48,"value":1838}," be opinionated.",{"type":42,"tag":117,"props":1840,"children":1841},{},[1842,1847,1849,1854],{"type":42,"tag":91,"props":1843,"children":1844},{},[1845],{"type":48,"value":1846},"Safety-critical systems.",{"type":48,"value":1848}," \"Everything is a file\" uniformity can obscure critical distinctions. When deleting a configuration file and deleting a production database use the same interface, uniformity works against you. Sometimes different things should ",{"type":42,"tag":73,"props":1850,"children":1851},{},[1852],{"type":48,"value":1853},"feel",{"type":48,"value":1855}," different.",{"type":42,"tag":117,"props":1857,"children":1858},{},[1859,1864],{"type":42,"tag":91,"props":1860,"children":1861},{},[1862],{"type":48,"value":1863},"Exploratory\u002Fcreative domains.",{"type":48,"value":1865}," \"Do one thing well\" assumes you know what the things are. In novel domains, the responsibility boundaries aren't clear yet. Premature decomposition creates arbitrary boundaries that must be redrawn as understanding deepens.",{"type":42,"tag":1588,"props":1867,"children":1869},{"id":1868},"the-meta-principle",[1870],{"type":48,"value":1871},"The Meta-Principle",{"type":42,"tag":51,"props":1873,"children":1874},{},[1875,1877,1882,1884,1889],{"type":48,"value":1876},"The Unix philosophy is, itself, a mechanism — not a policy. It provides ",{"type":42,"tag":73,"props":1878,"children":1879},{},[1880],{"type":48,"value":1881},"thinking tools",{"type":48,"value":1883}," for evaluating designs, not ",{"type":42,"tag":73,"props":1885,"children":1886},{},[1887],{"type":48,"value":1888},"rules",{"type":48,"value":1890}," for making them. The judgment of when to apply each principle, how strongly, and when to deliberately violate one in service of another — that's the policy, and it's yours to make.",{"items":1892,"total":1971},[1893,1905,1912,1922,1934,1949,1961],{"slug":1894,"name":1894,"fn":1895,"description":1896,"org":1897,"tags":1898,"stars":25,"repoUrl":26,"updatedAt":1904},"design-philosophy-domain-driven","model complex systems with domain-driven design","Domain-Driven Design as a lens for system architecture — bounded contexts, aggregates, ubiquitous language, context mapping, domain events, and strategic vs tactical patterns. Use when modeling complex business domains, defining service boundaries, or evaluating whether a system's structure reflects its domain.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1899,1900,1903],{"name":13,"slug":14,"type":15},{"name":1901,"slug":1902,"type":15},"Data Modeling","data-modeling",{"name":17,"slug":18,"type":15},"2026-07-07T06:53:28.678913",{"slug":4,"name":4,"fn":5,"description":6,"org":1906,"tags":1907,"stars":25,"repoUrl":26,"updatedAt":27},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1908,1909,1910,1911],{"name":13,"slug":14,"type":15},{"name":23,"slug":24,"type":15},{"name":20,"slug":21,"type":15},{"name":17,"slug":18,"type":15},{"slug":1913,"name":1913,"fn":1914,"description":1915,"org":1916,"tags":1917,"stars":25,"repoUrl":26,"updatedAt":1921},"system-type-distributed","apply distributed systems design patterns","Foundational patterns for distributed systems — consensus, consistency models, replication, partitioning, clock synchronization, distributed transactions, and failure modes. Use when designing or evaluating any system that spans multiple nodes, processes, or failure domains.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1918,1919,1920],{"name":13,"slug":14,"type":15},{"name":23,"slug":24,"type":15},{"name":17,"slug":18,"type":15},"2026-05-13T06:14:49.388552",{"slug":1923,"name":1923,"fn":1924,"description":1925,"org":1926,"tags":1927,"stars":25,"repoUrl":26,"updatedAt":1933},"system-type-event-driven","design event-driven and message-based systems","Domain patterns for event-driven and message-based systems — pub\u002Fsub, event sourcing, CQRS, sagas, delivery guarantees, schema evolution, and failure modes. Use when designing or evaluating systems built around events, messages, or asynchronous workflows.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1928,1929,1932],{"name":13,"slug":14,"type":15},{"name":1930,"slug":1931,"type":15},"Messaging","messaging",{"name":17,"slug":18,"type":15},"2026-07-07T06:53:27.291427",{"slug":1935,"name":1935,"fn":1936,"description":1937,"org":1938,"tags":1939,"stars":25,"repoUrl":26,"updatedAt":1948},"system-type-ml-serving","design ML serving and training systems","Domain patterns for ML\u002FAI serving and training systems — model serving, feature stores, training pipelines, experiment tracking, A\u002FB testing, GPU scheduling, and failure modes. Use when designing or evaluating machine learning infrastructure, model serving platforms, or AI-powered product features.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1940,1943,1946,1947],{"name":1941,"slug":1942,"type":15},"AI Infrastructure","ai-infrastructure",{"name":1944,"slug":1945,"type":15},"Deep Learning","deep-learning",{"name":23,"slug":24,"type":15},{"name":17,"slug":18,"type":15},"2026-07-03T16:31:59.997224",{"slug":1950,"name":1950,"fn":1951,"description":1952,"org":1953,"tags":1954,"stars":25,"repoUrl":26,"updatedAt":1960},"system-type-real-time","design real-time and collaborative systems","Domain patterns for real-time and collaborative systems — persistent connections, state synchronization, conflict resolution, presence, fan-out, and failure modes. Use when designing or evaluating chat systems, collaborative editors, live dashboards, gaming backends, or any system with bidirectional real-time communication.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1955,1956,1959],{"name":13,"slug":14,"type":15},{"name":1957,"slug":1958,"type":15},"Real-time","real-time",{"name":17,"slug":18,"type":15},"2026-07-07T06:53:26.004577",{"slug":1962,"name":1962,"fn":1963,"description":1964,"org":1965,"tags":1966,"stars":25,"repoUrl":26,"updatedAt":1970},"systems-design-review-methodology","perform systems design reviews","Use when the \u002Fsystems-design-review mode is active. 7-step design review methodology -- understand the design, classify the system, evaluate against codebase, adversarial analysis, tradeoff validation, synthesis, and action items. Governs conversation flow, delegation patterns, and user validation checkpoints.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1967,1968,1969],{"name":13,"slug":14,"type":15},{"name":23,"slug":24,"type":15},{"name":17,"slug":18,"type":15},"2026-07-03T16:31:58.725837",7,{"items":1973,"total":2164},[1974,1994,2015,2036,2049,2066,2077,2090,2105,2120,2139,2152],{"slug":1975,"name":1975,"fn":1976,"description":1977,"org":1978,"tags":1979,"stars":1991,"repoUrl":1992,"updatedAt":1993},"rushstack-best-practices","manage Rush monorepos with best practices","Provides best practices and guidance for working with Rush monorepos. Use when the user is working in a Rush-based repository, asks about Rush commands (install, update, build, rebuild), needs help with project selection, dependency management, build caching, subspace configuration, or troubleshooting Rush-specific issues.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1980,1981,1984,1985,1988],{"name":23,"slug":24,"type":15},{"name":1982,"slug":1983,"type":15},"Local Development","local-development",{"name":9,"slug":8,"type":15},{"name":1986,"slug":1987,"type":15},"Project Management","project-management",{"name":1989,"slug":1990,"type":15},"Rush","rush",6484,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Frushstack","2026-04-06T18:34:44.965032",{"slug":1995,"name":1995,"fn":1996,"description":1997,"org":1998,"tags":1999,"stars":2012,"repoUrl":2013,"updatedAt":2014},"azure-ai-agents-persistent-dotnet","build AI agents with Azure .NET SDK","Azure AI Agents Persistent SDK for .NET. Low-level SDK for creating and managing AI agents with threads, messages, runs, and tools. Use for agent CRUD, conversation threads, streaming responses, function calling, file search, and code interpreter. Triggers: \"PersistentAgentsClient\", \"persistent agents\", \"agent threads\", \"agent runs\", \"streaming agents\", \"function calling agents .NET\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2000,2003,2006,2009],{"name":2001,"slug":2002,"type":15},".NET","net",{"name":2004,"slug":2005,"type":15},"Agents","agents",{"name":2007,"slug":2008,"type":15},"Azure","azure",{"name":2010,"slug":2011,"type":15},"LLM","llm",2804,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002Fskills","2026-07-03T16:32:10.297433",{"slug":2016,"name":2016,"fn":2017,"description":2018,"org":2019,"tags":2020,"stars":2012,"repoUrl":2013,"updatedAt":2035},"azure-ai-anomalydetector-java","build anomaly detection applications with Java","Build anomaly detection applications with Azure AI Anomaly Detector SDK for Java. Use when implementing univariate\u002Fmultivariate anomaly detection, time-series analysis, or AI-powered monitoring.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2021,2024,2025,2028,2031,2032],{"name":2022,"slug":2023,"type":15},"Analytics","analytics",{"name":2007,"slug":2008,"type":15},{"name":2026,"slug":2027,"type":15},"Data Analysis","data-analysis",{"name":2029,"slug":2030,"type":15},"Java","java",{"name":9,"slug":8,"type":15},{"name":2033,"slug":2034,"type":15},"Monitoring","monitoring","2026-05-13T06:14:16.261754",{"slug":2037,"name":2037,"fn":2038,"description":2039,"org":2040,"tags":2041,"stars":2012,"repoUrl":2013,"updatedAt":2048},"azure-ai-contentsafety-java","build content moderation applications with Azure AI","Build content moderation applications with Azure AI Content Safety SDK for Java. Use when implementing text\u002Fimage analysis, blocklist management, or harm detection for hate, violence, sexual content, and self-harm.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2042,2043,2044,2045],{"name":1941,"slug":1942,"type":15},{"name":2007,"slug":2008,"type":15},{"name":2029,"slug":2030,"type":15},{"name":2046,"slug":2047,"type":15},"Security","security","2026-07-07T06:53:31.293235",{"slug":2050,"name":2050,"fn":2051,"description":2052,"org":2053,"tags":2054,"stars":2012,"repoUrl":2013,"updatedAt":2065},"azure-ai-contentsafety-py","detect harmful content with Azure AI Content Safety","Azure AI Content Safety SDK for Python. Use for detecting harmful content in text and images with multi-severity classification.\nTriggers: \"azure-ai-contentsafety\", \"ContentSafetyClient\", \"content moderation\", \"harmful content\", \"text analysis\", \"image analysis\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2055,2056,2059,2060,2061,2064],{"name":2007,"slug":2008,"type":15},{"name":2057,"slug":2058,"type":15},"Compliance","compliance",{"name":2010,"slug":2011,"type":15},{"name":9,"slug":8,"type":15},{"name":2062,"slug":2063,"type":15},"Python","python",{"name":2046,"slug":2047,"type":15},"2026-07-18T05:14:23.017504",{"slug":2067,"name":2067,"fn":2068,"description":2069,"org":2070,"tags":2071,"stars":2012,"repoUrl":2013,"updatedAt":2076},"azure-ai-language-conversations-py","implement conversational language understanding with Python","Implement Conversational Language Understanding (CLU) using the azure-ai-language-conversations Python SDK. Use when working with ConversationAnalysisClient to analyze conversation intent and entities, building NLP features, or integrating language understanding into applications.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2072,2073,2074,2075],{"name":2022,"slug":2023,"type":15},{"name":2007,"slug":2008,"type":15},{"name":2010,"slug":2011,"type":15},{"name":2062,"slug":2063,"type":15},"2026-07-31T05:54:29.068751",{"slug":2078,"name":2078,"fn":2079,"description":2080,"org":2081,"tags":2082,"stars":2012,"repoUrl":2013,"updatedAt":2089},"azure-ai-translation-text-py","translate text using Azure AI services","Azure AI Text Translation SDK for real-time text translation, transliteration, language detection, and dictionary lookup. Use for translating text content in applications.\nTriggers: \"text translation\", \"translator\", \"translate text\", \"transliterate\", \"TextTranslationClient\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2083,2086,2087,2088],{"name":2084,"slug":2085,"type":15},"API Development","api-development",{"name":2007,"slug":2008,"type":15},{"name":9,"slug":8,"type":15},{"name":2062,"slug":2063,"type":15},"2026-07-18T05:14:16.988376",{"slug":2091,"name":2091,"fn":2092,"description":2093,"org":2094,"tags":2095,"stars":2012,"repoUrl":2013,"updatedAt":2104},"azure-ai-vision-imageanalysis-py","analyze images with Azure AI Vision","Azure AI Vision Image Analysis SDK for captions, tags, objects, OCR, people detection, and smart cropping. Use for computer vision and image understanding tasks.\nTriggers: \"image analysis\", \"computer vision\", \"OCR\", \"object detection\", \"ImageAnalysisClient\", \"image caption\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2096,2097,2100,2103],{"name":2007,"slug":2008,"type":15},{"name":2098,"slug":2099,"type":15},"Computer Vision","computer-vision",{"name":2101,"slug":2102,"type":15},"Images","images",{"name":2062,"slug":2063,"type":15},"2026-07-18T05:14:18.007737",{"slug":2106,"name":2106,"fn":2107,"description":2108,"org":2109,"tags":2110,"stars":2012,"repoUrl":2013,"updatedAt":2119},"azure-appconfiguration-java","manage configuration with Azure App Configuration","Azure App Configuration SDK for Java. Centralized application configuration management with key-value settings, feature flags, and snapshots.\nTriggers: \"ConfigurationClient java\", \"app configuration java\", \"feature flag java\", \"configuration setting java\", \"azure config java\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2111,2112,2115,2118],{"name":2007,"slug":2008,"type":15},{"name":2113,"slug":2114,"type":15},"Configuration","configuration",{"name":2116,"slug":2117,"type":15},"Feature Flags","feature-flags",{"name":2029,"slug":2030,"type":15},"2026-07-03T16:32:01.278468",{"slug":2121,"name":2121,"fn":2122,"description":2123,"org":2124,"tags":2125,"stars":2012,"repoUrl":2013,"updatedAt":2138},"azure-cosmos-rust","build applications with Azure Cosmos DB","Azure Cosmos DB library for Rust (NoSQL API). Document CRUD, containers, and globally distributed data.\nTriggers: \"cosmos db rust\", \"CosmosClient rust\", \"document crud rust\", \"NoSQL rust\", \"partition key rust\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2126,2129,2132,2135],{"name":2127,"slug":2128,"type":15},"Cosmos DB","cosmos-db",{"name":2130,"slug":2131,"type":15},"Database","database",{"name":2133,"slug":2134,"type":15},"NoSQL","nosql",{"name":2136,"slug":2137,"type":15},"Rust","rust","2026-07-31T05:54:27.021432",{"slug":2140,"name":2140,"fn":2122,"description":2141,"org":2142,"tags":2143,"stars":2012,"repoUrl":2013,"updatedAt":2151},"azure-cosmos-ts","Azure Cosmos DB JavaScript\u002FTypeScript SDK (@azure\u002Fcosmos) for data plane operations. Use for CRUD operations on documents, queries, bulk operations, and container management. Triggers: \"Cosmos DB\", \"@azure\u002Fcosmos\", \"CosmosClient\", \"document CRUD\", \"NoSQL queries\", \"bulk operations\", \"partition key\", \"container.items\".\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2144,2145,2146,2147,2148],{"name":2127,"slug":2128,"type":15},{"name":2130,"slug":2131,"type":15},{"name":9,"slug":8,"type":15},{"name":2133,"slug":2134,"type":15},{"name":2149,"slug":2150,"type":15},"TypeScript","typescript","2026-07-03T16:31:19.368382",{"slug":2153,"name":2153,"fn":2154,"description":2155,"org":2156,"tags":2157,"stars":2012,"repoUrl":2013,"updatedAt":2163},"azure-data-tables-java","build table storage applications with Java","Build table storage applications with Azure Tables SDK for Java. Use when working with Azure Table Storage or Cosmos DB Table API for NoSQL key-value data, schemaless storage, or structured data at scale.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2158,2159,2160,2161,2162],{"name":2007,"slug":2008,"type":15},{"name":2127,"slug":2128,"type":15},{"name":2130,"slug":2131,"type":15},{"name":2029,"slug":2030,"type":15},{"name":2133,"slug":2134,"type":15},"2026-05-13T06:14:17.582229",267]