agentleFS
h2coneh2cone/agent-packs/skills/ousterhout-software-design/SKILL.md

ousterhout-software-design

Skill0 starsChanged 26 days agoMITView on GitHub

Knowledge base from \"A Philosophy of Software Design, 2nd Edition\" by John K. Ousterhout. Use when applying Ousterhout's frameworks for managing complexity, deep modules, information hiding, strategic programming, comments, naming, and everyday software design decisions, or when studying/referencing the book's concepts.

2 other projects use a version of this.

Adopted by

Most recently taken up by

The file

We split this skill into the rules it gives an agent

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

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈3

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 2

    Very specific

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

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    With a topic: - ask about complexity, deep modules, comments, errors, performance, etc..

    line 14
  2. Very specific:

    With a chapter: - ask for ch04 or "chapter 4".

    line 15
  3. Distinctive:

    Browse: - ask "what chapters do you have?" to see the full index.

    line 16
  4. Distinctive:

    When you ask about a topic not fully covered in Core Frameworks below, I read the relevant chapter file(s) before answering.

    line 18
  5. Distinctive:

    Pull complexity downward: When a module has unavoidable, related complexity, absorb it internally rather than punting to many callers (a …

    line 38

≈ “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, or chapter number like ch04] -->

A Philosophy of Software Design (2nd Edition)

Author: John K. Ousterhout (Stanford; creator of Tcl) | Pages: ~190 (210 PDF) | Chapters: 22 | Generated: 2026-08-02

How to Use This Skill

  • Without arguments - load the core frameworks below for reference.
  • With a topic - ask about complexity, deep modules, comments, errors, performance, etc.; I find and read the relevant chapter file before answering.
  • With a chapter - ask for ch04 or "chapter 4"; I load that specific chapter summary.
  • Browse - ask "what chapters do you have?" to see the full index.

When you ask about a topic not fully covered in Core Frameworks below, I read the relevant chapter file(s) before answering. For fast decisions, see cheatsheet.md (the 16 principles + 14 red flags as decision rules).


Core Frameworks & Mental Models

The book is about one thing: complexity. Complexity is anything that makes a system hard to understand and modify. Everything below is a lever against it.

Complexity (the enemy). Defined practically, not by size: C = Σ(cₚ × tₚ) - complexity of each part weighted by developer time spent there. Three symptoms: change amplification (one change touches many places), cognitive load (how much you must know), unknown unknowns (not obvious what to modify or what info you need - the worst). Two causes: dependencies (code not isolable) and obscurity (important info not obvious). Complexity is incremental - it accumulates in thousands of small chunks - so adopt zero tolerance. The positive goal is an obvious system. (Ch 2, 18)

Strategic vs. tactical programming. Tactical = "get it working now" (accumulates complexity); strategic = "produce a great design that also works" (invests continually). The tactical tornado ships fast and leaves wreckage. Invest ~10–20% of dev time continually (proactive + reactive); payback ~6–18 months; technical debt is mostly never repaid. (Ch 3)

Modules should be deep. Visualize a module as a rectangle: area = functionality, top edge = interface complexity. Deep = much functionality behind a simple interface. A simple interface matters more than a simple implementation. Interfaces have formal (code) and informal (comments) parts; informal is usually larger. An abstraction that omits important details is a false abstraction. Resist classitis. (Ch 4)

Information hiding (and leakage). Each module encapsulates design decisions invisible in its interface. The opposite - information leakage, a decision reflected in multiple modules - is a top red flag, often invisible (back-door leakage). Decompose around knowledge, not execution order (temporal decomposition is an anti-pattern). private ≠ hidden; getters/setters leak. Make the common case simple with defaults; "do the right thing without being asked." (Ch 5)

General-purpose modules are deeper. Over-specialization may be the single greatest cause of complexity. Make modules "somewhat general-purpose": functionality for today, interface not tied to today. Push specialization up (to callers) or down (to pluggable low-level modules). Eliminate special cases by designing the normal case to handle edges for free. (Ch 6)

Different layer, different abstraction. Each layer must earn its keep with a different abstraction. Pass-through methods (forward a similar signature, add nothing) and decorators signal confused responsibility - redistribute, expose, or merge. Same signatures are fine only for dispatchers and multiple implementations. Collect pass-through variables into a context object. (Ch 7)

Pull complexity downward. When a module has unavoidable, related complexity, absorb it internally rather than punting to many callers (a simple interface > a simple implementation). Avoid configuration parameters; auto-compute values and default them. Pull down only complexity that's related and simplifies elsewhere. (Ch 8)

Define errors out of existence. Exceptions are a major complexity source; reduce the places they're handled. Best: redefine semantics so the error can't occur. Else: mask low (TCP resends), aggregate high (one top-level handler), or just crash for unrecoverable, infrequent errors. Expose exceptions only when the info is genuinely needed outside. (Ch 10)

Design it twice. For each major decision, sketch ≥2 radically different alternatives; compare on ease-of-use for higher-level code first; choose, combine, or let the weaknesses drive a new design. Costs ~1–2 hrs for a class; hard for smart people to embrace, but the problems are just hard. (Ch 11)

Comments are a design tool. Comments capture what code can't and are fundamental to abstraction - without them, complexity isn't hidden. Describe the non-obvious (a first-time reader's view) at a different level than the code: lower for precision, higher for intuition; never repeat the code. Write comments first - a long/hard comment is a red flag (Hard to Describe) signaling a bad abstraction, not a writing problem. (Ch 12, 13, 15)

Choosing names. Names are abstraction: precise and consistent. Booleans are predicates; avoid generic nouns and type-encoding. If a name is hard to pick, the design may be muddy - let naming drive refactoring. (Ch 14)

Decide what matters. Structure around what matters; minimize what matters (and where it matters); emphasize it via prominence, repetition, centrality. Look for leverage - one decision that solves or clarifies many. "Good taste" = distinguishing important from unimportant; it underlies every other principle. (Ch 21)

The author's own distillation: 16 design principles and 14 red flags are in cheatsheet.md as decision rules.


Chapter Index

#TitleKey Frameworks
ch01Introduction (It's All About Complexity)Two approaches to complexity; continuous design; red flags
ch02The Nature of Complexity3 symptoms; 2 causes; incremental; zero tolerance; obvious
ch03Working Code Isn't EnoughStrategic vs tactical; tactical tornado; 10–20% investment; technical debt
ch04Modules Should Be DeepInterface/impl; formal/informal; abstraction; deep vs shallow; classitis
ch05Information Hiding (and Leakage)Hiding; leakage; temporal decomposition; defaults; overexposure
ch06General-Purpose Modules are DeeperSomewhat-general; push specialization; eliminate special cases; false abstraction
ch07Different Layer, Different AbstractionPass-through methods/variables; decorators; context object
ch08Pull Complexity DownwardsSimple interface > simple impl; avoid config params
ch09Better Together Or Better Apart?Costs of subdivision; bring-together rules; split/join methods; depth > length
ch10Define Errors Out of ExistenceMask; aggregate; just crash; exception promotion
ch11Design it TwiceMultiple alternatives; compare; weakness-driven redesign
ch12Why Write Comments? The Four ExcusesComments capture code-can't; fundamental to abstraction; refutes excuses
ch13Comments Describe the Non-ObviousPrecision vs intuition; interface vs implementation docs; cross-module
ch14Choosing NamesPrecision; consistency; avoid extra words; Hard to Pick Name
ch15Write The Comments FirstComments-first workflow; comments as design tool; Hard to Describe
ch16Modifying Existing CodeStay strategic; comments near code & once; check diffs
ch17ConsistencyCognitive leverage; document/enforce/when-in-Rome; invariants
ch18Code Should be ObviousWhitespace; avoid generic containers; design for reading
ch19Software TrendsInterface vs impl inheritance; agile/TDD critique; patterns; getters/setters
ch20Designing for PerformanceAwareness; measure; design around the critical path
ch21Decide What MattersLeverage; minimize; emphasize (prominence/repetition/centrality); good taste
ch22ConclusionComplexity as the one thing; investment compounds; design is fun

Topic Index

  • Abstraction / false abstraction -> ch04, ch06
  • Agile development -> ch01, ch19
  • Caching / performance -> ch20
  • Change amplification -> ch02
  • Classitis / shallow modules -> ch04, ch19
  • Cognitive load -> ch02
  • Comments (design tool, first, non-obvious) -> ch12, ch13, ch15, ch16
  • Complexity (definition, causes, symptoms) -> ch02
  • Composition vs inheritance -> ch19
  • Configuration parameters -> ch08
  • Conjoined methods -> ch09
  • Consistency / invariants -> ch17
  • Context object -> ch07
  • Cross-module decisions / designNotes -> ch13, ch16
  • Decorators -> ch07, ch19
  • Deep modules -> ch04, ch06, ch08
  • Defaults / "do the right thing" -> ch05
  • Dependencies -> ch02, ch07
  • Design it twice -> ch11, ch21
  • Design patterns -> ch17, ch19
  • Device drivers -> ch06
  • Errors (define out / mask / aggregate / crash) -> ch10
  • Exception handling -> ch10
  • General-purpose modules -> ch06
  • Getters/setters -> ch19
  • Information hiding / leakage -> ch05
  • Inheritance (interface vs implementation) -> ch19
  • Investment mindset / technical debt -> ch03
  • Leverage / decide what matters -> ch21
  • Modifying existing code -> ch16
  • Modular design -> ch04
  • Naming -> ch14, ch18
  • Obscurity / obviousness -> ch02, ch18
  • Overexposure -> ch05
  • Pass-through methods/variables -> ch07
  • Performance -> ch20
  • Pull complexity downward -> ch08, ch10
  • Red flags -> ch01, ch02, ch05, ch07, ch09, ch13, ch14, ch15, ch18 (full list: cheatsheet.md)
  • Repetition -> ch09
  • Special cases -> ch06, ch10, ch20
  • Strategic vs tactical programming -> ch03, ch16, ch19
  • Temporal decomposition -> ch05
  • Test-driven development / unit tests -> ch19
  • Together vs apart -> ch09
  • Unknown unknowns -> ch02
  • Waterfall model -> ch01
  • Zero tolerance -> ch02, ch03

Supporting Files

  • glossary.md - all key terms with definitions and chapter refs
  • patterns.md - the book's reusable techniques (when/how/trade-offs)
  • cheatsheet.md - the 16 design principles + 14 red flags as decision rules, thresholds, and decision trees

Scope & Limits

This skill covers the book's content only. It is conceptual/design guidance, not a coding library - combine it with project-specific tools for hands-on implementation. For topics beyond this book (e.g. specific algorithms, domain architectures), check related skills or ask the agent directly. The book's examples are in Java/C++; the principles apply to any language and to non-class modules (functions, subsystems, services).

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.