General
ousterhout-principles - Claude MCP Skill
Apply Ousterhout's software design principles: detect shallow modules, information leakage, and complexity red flags. Use when reviewing code, designing modules, refactoring, or discussing architecture.
SEO Guide: Enhance your AI agent with the ousterhout-principles tool. This Model Context Protocol (MCP) server allows Claude Desktop and other LLMs to apply ousterhout's software design principles: detect shallow modules, information leakage, and comp... Download and configure this skill to unlock new capabilities for your AI workflow.
Documentation
SKILL.md# Ousterhout's Software Design Principles Quick checks for applying John Ousterhout's "A Philosophy of Software Design" principles. Managing complexity is the primary challenge in software engineering. ## Core Formula **Module Value = Functionality - Interface Complexity** The best modules are **deep**: simple interfaces hiding powerful implementations. ## 1. Deep vs Shallow Module Check ### Classic Deep Module Example **Unix I/O**: Four simple operations (open, read, write, close) hide massive complexity (buffering, disk management, filesystem, drivers, caching). ### Assessment Questions **Functionality Assessment:** - How much does this module actually do? - What complexity does it hide from callers? - Could I significantly change implementation without breaking callers? **Interface Assessment:** - How many public methods/functions? - How many parameters do they require? - How much must callers know to use it correctly? **The Feel Test:** - Interface complexity ā implementation complexity? ā **Shallow** (eliminate or deepen) - Simple interface, powerful implementation? ā **Deep** (good!) - Just wrapping another module? ā **Shallow** (probably unnecessary abstraction) ### Warning Signs ā **Shallow Module Indicators:** - Wrapper class exposing most wrapped methods - Pass-through functions adding no semantic value - Abstraction hiding little complexity - Thin layer that could be eliminated - Interface almost as complex as implementation ā **Deep Module Indicators:** - Simple interface (few methods, clear parameters) - Powerful functionality (does a lot) - Hides design decisions - Changing internals doesn't break callers - Worth the abstraction cost ## 2. Information Leakage Check ### Core Test **"If I change implementation details, do callers break?"** If YES ā You have information leakage. ### Common Leakage Patterns **Database Schema Leakage:** ``` ā BAD: Return raw database rows/arrays - Callers depend on column order - Schema changes break calling code - Implementation (SQL) leaks through interface ā GOOD: Return domain objects - Hide schema behind types - Callers use named properties - Schema refactoring transparent to callers ``` **Internal Data Structure Leakage:** ``` ā BAD: Expose internal buffer/cache structure - Callers know about your storage choices - Can't change data structures freely - Implementation details in public API ā GOOD: Provide abstract query interface - Hide how data is stored - Expose "what" not "how" - Free to optimize internals ``` **Implementation Detail Leakage:** ``` ā BAD: Configuration forcing caller knowledge - Expose internal IDs, indices, ordering - Require callers to know implementation - Changes ripple to all callers ā GOOD: Domain-centric interface - Use domain language - Hide technical implementation - Stable despite internal changes ``` ### Encapsulation Check Ask yourself: - Can I refactor internals without breaking callers? - Do callers know about my implementation choices? - Does my interface reveal "how" or just "what"? - Would changing my data structure break callers? **Principle**: Each module should hide design decisions from others. ## 3. Red Flag Scanner ### Critical Red Flags (Avoid) **Generic Names:** - `Manager`, `Util`, `Helper` ā Vague, non-specific - `Service`, `Handler`, `Processor` ā Sometimes justified, often lazy - `Base`, `Abstract` ā Prefix anti-patterns **Ask**: Does name reveal **what** it does? Or just **that** it does something? **Temporal Decomposition:** - `step1()`, `step2()`, `step3()` - `phase1()`, `phase2()` - `initialize()`, `process()`, `finalize()` **Problem**: Organized by **WHEN** executed, not **WHAT** they do. **Better**: Organize by functionality. Name by purpose, not sequence. ### Warning Signs **Pass-Through Methods:** - Method just delegates to another class - Adds no transformation or logic - No semantic value - Just indirection for indirection's sake **Configuration Overload:** - Too many parameters/options - Every implementation detail exposed - Interface complexity ā implementation - Callers must understand internals ### Context-Aware Exceptions Some generic names have domain justification: - `EventManager` in event-driven system ā Acceptable - But `EventBus` or `EventDispatcher` still better (more specific) **Principle**: Prefer specific domain terms over generic technical terms. ### Quick Scan Questions When reviewing a module: 1. Does name reveal what it does (not just that it exists)? 2. Is it organized by execution order (temporal anti-pattern)? 3. Does it just wrap another module without adding value? 4. Could I give it a more specific, intention-revealing name? 5. Does it have too many configuration options? ## Application Workflow **When designing:** 1. Check module depth (value = functionality - interface complexity) 2. Ensure information hiding (callers isolated from implementation) 3. Avoid red flag names (be specific, avoid generic terms) **When reviewing:** 1. Scan for Manager/Util/Helper (red flags) 2. Test: "If implementation changes, do callers break?" (leakage) 3. Assess: Simple interface + powerful implementation? (depth) **When refactoring:** 1. Identify shallow modules ā Consider eliminating or deepening 2. Find information leakage ā Add encapsulation 3. Replace generic names ā Use domain-specific terms ## Key Principles Summary 1. **Deep Modules**: Simple interfaces hiding powerful implementations 2. **Information Hiding**: Each module hides design decisions from others 3. **Avoid Complexity**: Fight generic names, temporal decomposition, pass-through methods 4. **YAGNI**: Question every piece not solving an immediate need 5. **Readability Over Cleverness**: Code is read more than written **Remember**: Complexity is anything that makes software hard to understand or modify. Fight it with every decision. ## References - [simplicity-tenets.md](references/simplicity-tenets.md) - YAGNI, complexity types, warning signs
Signals
Information
- Repository
- phrazzld/claude-config
- Author
- phrazzld
- Last Sync
- 1/22/2026
- Repo Updated
- 1/17/2026
- Created
- 1/13/2026
Reviews (0)
No reviews yet. Be the first to review this skill!
Related Skills
upgrade-nodejs
Upgrading Bun's Self-Reported Node.js Version
cursorrules
CrewAI Development Rules
cn-check
Install and run the Continue CLI (`cn`) to execute AI agent checks on local code changes. Use when asked to "run checks", "lint with AI", "review my changes with cn", or set up Continue CI locally.
CLAUDE
CLAUDE.md
Related Guides
Bear Notes Claude Skill: Your AI-Powered Note-Taking Assistant
Learn how to use the bear-notes Claude skill. Complete guide with installation instructions and examples.
Mastering tmux with Claude: A Complete Guide to the tmux Claude Skill
Learn how to use the tmux Claude skill. Complete guide with installation instructions and examples.
OpenAI Whisper API Claude Skill: Complete Guide to AI-Powered Audio Transcription
Learn how to use the openai-whisper-api Claude skill. Complete guide with installation instructions and examples.