agentleFS
BipBop-LabsBipBop-Labs/bipbop-skills/skills/ousterhout-software-design/SKILL.md

ousterhout-software-design

Skill3 starsChanged 44 days agoMITView on GitHub

Knowledge base from \"A Philosophy of Software Design\" by John Ousterhout. Use when designing or reviewing code for complexity, module depth, information hiding, interface design, error handling, comments, naming, or performance — or when a design decision needs a rationale beyond taste.

2 other projects use a version of this, 1 of them edited.

Adopted by

Most recently taken up by

  • Other versions2 projects use a version of this.

    Word for word · 0

    None found.

    Edited · 1

    1. h2cone/agent-packs★ 011% same

    Wrote their own version · 1

    1. tslateman/skills★ 1same name

    How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.

  • In this repository7 other files it gives its agents.

The file

We split this skill into the rules it gives an agent

2 rules. About 0 are common, 2 are distinctive, and 0 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈2

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 0

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Every chapter file carries the book's actual code examples and worked cases, so recommendations can cite a concrete precedent rather than a …

    line 18
  2. Distinctive:

    Only two tools exist: eliminate complexity (simpler, more obvious code) or encapsulate it (modular design).

    line 32

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md
<!-- argument-hint: [topic, framework name, red flag, or chapter number] -->

A Philosophy of Software Design

Author: John Ousterhout | Pages: ~188 | Chapters: 21 | Generated: 2026-08-10

How to Use This Skill

  • While writing code — apply the red flags below as stop-and-redesign signals; consult cheatsheet.md for the decision rules.
  • While reviewing code — the red flag table is the review checklist. Ousterhout designed the book for exactly this use. Report only red flags the diff introduces or worsens, each with file:line, the flag, and a concrete fix. Never report praise ("improves information hiding"), "no recommendation" items, or speculative redesigns with no named cost. Read the full file before claiming something is missing. Unsure after checking → drop it. At most 5 findings, one to three lines each, no intro, greeting, sign-off or summary of the change. No red flags → say so in one line; inside a review that combines other guides, say nothing and let that guide's format and cap rule.
  • With a topic — ask about deep modules, information hiding, exceptions, naming, comments, performance; I read the relevant chapter first.
  • With a chapter — ask for ch10; I load that file.

Every chapter file carries the book's actual code examples and worked cases, so recommendations can cite a concrete precedent rather than a slogan.


The Central Claim

Complexity is the fundamental limit on software — "anything related to the structure of a software system that makes it hard to understand and modify the system." It is caused by two things and shows up as three:

CausesSymptoms
Dependencies — code that can't be understood or changed in isolationChange amplification — a simple change touches many places
Obscurity — important information isn't obviousCognitive load — how much you must know to make a change
Unknown unknowns — you can't tell what you need to know ← the worst

Only two tools exist: eliminate complexity (simpler, more obvious code) or encapsulate it (modular design).

Complexity is incremental — never one catastrophe, always hundreds of small dependencies and obscurities. So sweat the small stuff, and adopt zero tolerance.


Core Frameworks

Deep modules (Ch 4) — The single most important idea. Picture a module as a rectangle: area = functionality, top edge = interface complexity. Deep = a lot of functionality behind a small interface. Ask of every class and method: is the interface much simpler than the implementation? Unix file I/O is five calls over hundreds of thousands of lines, unchanged for decades. A garbage collector has no interface — adding it shrinks the system's total interface. Conversely, "interfaces are good, but more, or larger, interfaces are not necessarily better," and "any method longer than N lines should be split" is wrong — it manufactures shallow methods.

Information hiding (Ch 5) — How modules become deep: each encapsulates design decisions that never appear in its interface. Note that private is not information hiding if getters and setters expose the same knowledge. Decompose by the knowledge needed for each task, not by the order operations occur — the latter is temporal decomposition and it leaks.

Somewhat general-purpose (Ch 6) — Functionality reflects today's needs; the interface does not. The payoff isn't speculative reuse, it's a simpler interface right now. A method with exactly one caller is a red flag for over-specialization.

Different layer, different abstraction (Ch 7) — Follow an operation through layers; the abstraction should change at each call. And the general test behind it: for every element you add — class, method, argument, interface — name the complexity it eliminates. If you can't, omit it.

Pull complexity downward (Ch 8) — "It is more important for a module to have a simple interface than a simple implementation." Most modules have more users than developers, so developer suffering is the cheaper suffering. The two ways people push complexity up: throwing an exception when unsure, and adding a configuration parameter when undecided.

Define errors out of existence (Ch 10) — Redefine semantics so the error case becomes normal. Not "delete a variable" but "ensure a variable no longer exists." Exceptions are part of your interface and the most expensive part, since they propagate through callers you don't control. Never throw because you don't know what to do — the caller won't know either. Four techniques, in order: define away → mask (place deep) → aggregate (place high) → crash.

Design it twice (Ch 11) — Sketch two or more radically different alternatives before committing, even when you're certain. Costs 1–2 hours per class. "No-one is good enough to get it right with their first try."

Comments as a design tool (Ch 15) — Write them first: class comment, then method comments and signatures with empty bodies, iterate, then variables, then bodies. Comments are a complexity meter: if the interface comment must describe the implementation's major features, the method is shallow; if a variable needs a long comment, the decomposition is wrong.

Strategic vs. tactical (Ch 3) — Working code is the floor, not the goal. Invest 10–20% of development time continuously; a degraded code base costs ≥20%. "Whenever you modify any code, try to find a way to improve the system design at least a little bit in the process. If you're not making the design better, you are probably making it worse." (Ch 16)

Obviousness (Ch 18) — Code is obvious when a reader's first guess is correct. Attack nonobviousness in order: (1) reduce the information needed — abstraction, eliminate special cases; (2) use information readers already have — conventions; (3) present it — names, comments. Comments are the third resort. And: "if a reader thinks it's not obvious, then it's not obvious."

Performance (Ch 20) — Clean design and speed are compatible; the Buffer rewrite got 2x faster, 20% smaller, and more readable at once. Never optimize on intuition. Simple code is fast for concrete reasons: no special-case checks, deeper classes doing more per call, fewer layer crossings.


The 14 Red Flags — the working checklist

Red flagTriggerCh
Shallow ModuleInterface isn't much simpler than implementation4
Information LeakageOne design decision reflected in multiple modules5
Temporal DecompositionStructure follows execution order, not information hiding5
OverexposureCommon features force learning rare ones5
Pass-Through MethodDoes nothing but forward its arguments7
RepetitionNontrivial code repeated9
Special-General MixtureGeneral mechanism carries code specialized to one use9
Conjoined MethodsCan't understand one without the other9
Comment Repeats CodeComment derivable from adjacent code13
Implementation Doc Contaminates InterfaceInterface comment describes internals13
Vague NameBroad enough to mean many things14
Hard to Pick NameCan't name it precisely → bad design14
Hard to DescribeNeeds a long comment to document → bad design15
Nonobvious CodeCan't be understood on a quick read18

Chapter Index

#TitleKey Frameworks
ch01Introduction (It's All About Complexity)eliminate vs. encapsulate, red-flag-driven design
ch02The Nature of Complexitycomplexity defined, 3 symptoms, 2 causes, weighted complexity
ch03Working Code Isn't Enoughtactical vs. strategic, 10–20% investment, tactical tornado
ch04Modules Should Be Deepdeep/shallow, abstraction, false abstraction, classitis
ch05Information Hiding (and Leakage)information hiding, leakage, temporal decomposition, defaults
ch06General-Purpose Modules are Deepersomewhat general-purpose, the three questions
ch07Different Layer, Different Abstractionlayer rule, net-gain test, decorator alternatives, context object
ch08Pull Complexity Downwardssimple interface > simple implementation, config-parameter test
ch09Better Together Or Better Apart?4 costs of subdivision, 4 signs of relatedness, method splitting
ch10Define Errors Out Of Existencedefine away, mask, aggregate, crash, error promotion
ch11Design it Twiceradically different alternatives, comparison criteria
ch12Why Write Comments? The Four Excusescomments enable abstraction, the 10% argument
ch13Comments Should Describe Things that Aren't Obvious4 categories, precision vs. intuition, designNotes
ch14Choosing Namescreate an image, precision + consistency, the block bug
ch15Write The Comments Firstcomments-first workflow, comments as complexity meter
ch16Modifying Existing Codestay strategic, comment placement, avoid duplication, check diffs
ch17Consistencycognitive leverage, invariants, automated enforcement, When in Rome
ch18Code Should be Obvious3 ways to make code obvious, white space, generic containers
ch19Software Trendsinheritance, agile, unit tests, TDD, patterns, getters/setters
ch20Designing for Performancecost awareness, measure first, critical path, Buffer rewrite
ch21Conclusionthe book's own summary; costs and payoff

Topic Index

  • Abstraction → ch04, ch06, ch12, ch13, ch18
  • Agile / incremental development → ch01, ch19
  • Comments → ch12, ch13, ch15, ch16, ch18
  • Configuration parameters → ch08
  • Consistency → ch14, ch17, ch18
  • Context objects / globals → ch07
  • Decorators → ch07, ch19
  • Deep modules → ch04, ch05, ch06, ch08, ch20
  • Dependencies → ch02, ch04, ch07, ch19
  • Design patterns → ch17, ch19
  • Duplication → ch09, ch16
  • Errors / exceptions → ch08, ch10, ch13
  • General- vs. special-purpose → ch06, ch09, ch10
  • Inheritance → ch19
  • Interface vs. implementation → ch04, ch07, ch13, ch15
  • Invariants → ch13, ch17
  • Layering → ch07, ch09, ch20
  • Method length / splitting → ch04, ch09, ch12
  • Naming → ch13, ch14, ch17, ch18
  • Obscurity / obviousness → ch02, ch13, ch18
  • Performance → ch19, ch20
  • Red flags → ch01, and one or more in ch04, 05, 07, 09, 13, 14, 15, 18
  • Refactoring → ch16, ch19, ch20
  • Special cases → ch10, ch17, ch20
  • Strategic vs. tactical → ch03, ch16, ch19
  • Testing → ch19
  • Whitespace / formatting → ch17, ch18

Supporting Files

  • cheatsheet.md — start here while coding: all 14 red flags, the 15 design principles, and the decision rules (split or join? throw or not? expose a parameter? optimize now?) plus every threshold and number in the book
  • patterns.md — the 20 named techniques and refactorings, each with when-to-use / how / trade-offs
  • glossary.md — every term with a one-line definition and chapter reference

Scope & Limits

Book content only. Examples are Java and C++ and the discussion is class-oriented, but Ousterhout notes the ideas apply to functions in non-OO languages and to subsystems and services alike.

Two things to carry carefully:

  • Apply everything with moderation. "Every rule has its exceptions, and every principle has its limits. If you take any design idea to its extreme, you will probably end up in a bad place." Most chapters have an explicit Taking it too far section; those are preserved in the chapter files and worth reading before pushing a principle hard.
  • Some positions are deliberately contrarian — against splitting methods by line count, against TDD, against getters and setters, against agile's defer-generality advice, against short Go-style names. The book argues each from complexity; the arguments are in the chapter files, so cite the reasoning rather than the verdict.

Absolute performance numbers in ch20 are from 2018; the ratios are the durable part.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.