# Unix Philosophy

> Apply UNIX philosophy principles to any coding or system-design conversation. Use this skill whenever the user is: writing or reviewing code, designing a function/module/service/CLI tool, asking about architecture, refactoring, simplifying, or splitting code up. Also trigger when you notice violations worth pointing out — god functions, flag arguments, mixed concerns, implicit state, overly complex interfaces. Works for any language (Python, Go, Bash, JS, Rust, etc.) and any scope (a 5-line function or a 5-service system). Keywords: design, refactor, architecture, simplify, module, interface, composable, pipeline, single responsibility, do one thing, clean code, separation of concerns.

- Skill: `khaledmahfouz5/unix-philosophy` (Agent Skill, multi-file: 5 files)
- Install (CLI): `npx skillmds@latest add khaledmahfouz5/unix-philosophy`
- Raw SKILL.md: https://api.skillmd.com/api/skills/khaledmahfouz5/unix-philosophy/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- Author: KhaledMahfouz5 (https://skillmd.com/u/khaledmahfouz5)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/khaledmahfouz5/unix-philosophy

---


# UNIX Philosophy Advisor

## Purpose

Guide the user toward software that does **one thing well**, can be **composed
with other programs**, and stays **simple enough to understand and change**.

The UNIX philosophy is not a rigid checklist — it is a set of design intuitions
distilled from decades of building tools that survive. Your job is to recognize
which principles are most relevant to the current situation and surface them
naturally, without turning every code review into a lecture.

---

## The 17 Principles (quick reference)

These come from Eric Raymond's *The Art of Unix Programming*. Keep this list in
mind as a mental model when advising.

| # | Principle | One-line rule |
|---|-----------|---------------|
| 1 | **Modularity** | Write simple parts connected by clean interfaces. |
| 2 | **Clarity** | Clarity is better than cleverness. |
| 3 | **Composition** | Design programs to be connected with other programs. |
| 4 | **Separation** | Separate policy from mechanism; separate interface from engine. |
| 5 | **Simplicity** | Design for simplicity; add complexity only where you must. |
| 6 | **Parsimony** | Write a big program only when nothing else will do. |
| 7 | **Transparency** | Design for visibility to make inspection and debugging easy. |
| 8 | **Robustness** | Robustness is the child of transparency and simplicity. |
| 9 | **Representation** | Fold knowledge into data so program logic can be stupid and robust. |
| 10 | **Least Surprise** | In interface design, always do the least surprising thing. |
| 11 | **Silence** | When a program has nothing surprising to say, it should say nothing. |
| 12 | **Repair** | Repair what you can — but when you must fail, fail noisily. |
| 13 | **Economy** | Programmer time is expensive; conserve it over machine time. |
| 14 | **Generation** | Avoid hand-hacking; write programs to write programs when you can. |
| 15 | **Optimization** | Prototype before polishing. Get it working before you optimize it. |
| 16 | **Diversity** | Distrust all claims for one true way. |
| 17 | **Extensibility** | Design for the future, because it will be here sooner than you think. |

For a deeper treatment of any principle, see `references/principles.md`.

---

## How to advise

**Match your output format to the context.** There is no fixed template — use
judgment:

- **User shares a code snippet** → inline critique with suggested rewrites.
  Point to the specific lines, name the principle(s) violated, show what
  cleaner code looks like. Be surgical; don't rewrite things that are fine.

- **User is designing something new** → ask one scoping question if needed,
  then walk through the relevant principles as design constraints. Help them
  draw boundaries between components before writing a single line.

- **User asks a general question** ("Is this a good design?", "How should I
  structure this?") → give a short direct answer, name the most relevant
  principle(s), and offer to go deeper.

- **You notice a violation worth flagging** → mention it briefly and explain
  *why* it matters, not just that it violates a rule. The goal is understanding,
  not compliance.

Keep responses focused. If only two principles are relevant, don't list all 17.

---

## Diagnosing violations

When reading code or a design description, look for these signals:

**Single-responsibility / Modularity**
- A function or module does more than one distinct thing.
- The name contains "and", "or", "also", or is vague like `process()`, `handle()`, `manage()`.
- To test or reuse one part you must drag along the whole thing.

**Composition / Separation**
- Business rules (policy) are tangled with the mechanism that executes them.
- Output is hardcoded to a specific sink (file, database, UI) instead of being
  returned or streamed so the caller can decide what to do with it.
- Functions produce side effects *and* return values *and* log *and* …

**Simplicity / Parsimony**
- The implementation is longer than the problem it solves.
- There is a simpler solution the user hasn't considered.
- Abstraction layers were added before they were needed (YAGNI).

**Transparency / Robustness**
- Errors are swallowed silently or converted to generic messages.
- State is implicit or global, making the program hard to inspect.
- Control flow is hard to follow: deeply nested conditions, magic returns.

**Representation**
- Logic encodes knowledge that could live in data (long `if/elif` chains for
  dispatch, hardcoded lookup tables embedded in code).

**Silence**
- Chatty output: progress spinners, verbose logs, or banners on normal success.
- A tool that says nothing on success is easier to compose in pipelines.

**Least Surprise / Extensibility**
- Flags or arguments change behavior in non-obvious ways.
- The interface makes the common case hard and the rare case easy.
- Callers have to know internal details to use the component correctly.

For more examples and canonical fixes, see `references/anti-patterns.md`.

---

## Before/after examples

### 1. Separation of policy and mechanism

**Before** (policy baked into mechanism):
```python
def save_user(user):
    if user["role"] == "admin":
        db.save(user, table="admins")
    else:
        db.save(user, table="users")
    send_email(user["email"], "Welcome!")
    log.info(f"Saved {user['email']}")
```

**After** (mechanism is dumb; caller decides policy):
```python
def save_user(user, table):
    db.save(user, table=table)

# caller decides policy
table = "admins" if user["role"] == "admin" else "users"
save_user(user, table)
send_welcome_email(user)
log.info(f"Saved {user['email']}")
```

---

### 2. Composition via standard streams (Silence + Composition)

**Before** (prints its own result, can't be composed):
```bash
get_users() { psql -c "SELECT email FROM users" | tail -n +3 | head -n -1; echo "Done."; }
```

**After** (outputs clean data, says nothing on success):
```bash
get_users() { psql -tAc "SELECT email FROM users"; }
# composes naturally: get_users | grep "@example.com" | mail_all
```

---

### 3. Representation over logic

**Before** (logic encodes data):
```python
def get_color(status):
    if status == "ok":    return "green"
    if status == "warn":  return "yellow"
    if status == "error": return "red"
    return "grey"
```

**After** (data encodes knowledge; logic is trivially simple):
```python
STATUS_COLORS = {"ok": "green", "warn": "yellow", "error": "red"}

def get_color(status):
    return STATUS_COLORS.get(status, "grey")
```

---

### 4. Modularity / single responsibility

**Before** (one function, three concerns):
```go
func HandleOrder(order Order) {
    if !order.IsValid() { panic("invalid") }
    db.Save(order)
    email.Send(order.CustomerEmail, "Your order is confirmed")
}
```

**After** (each function does one thing):
```go
func ValidateOrder(order Order) error { … }
func SaveOrder(order Order) error     { … }
func NotifyCustomer(email string)     { … }
```

---

## Guiding design conversations

When a user is starting something new, ask yourself:

1. **What is the one thing this component should do?** If you can't state it in
   a single sentence without "and", the boundary is wrong.
2. **What goes in, what comes out?** Prefer values over side effects. Prefer
   text/data streams over tightly coupled objects where composition matters.
3. **Where does policy live?** Push decisions about *what* to do up to the
   caller; keep the component focused on *how* to do one thing.
4. **What is the failure contract?** Fail loudly (return an error, raise an
   exception, exit non-zero) rather than silently producing wrong output.
5. **Can this be smaller?** The best code is code you didn't write.

---

## What this skill is not

- It is not a code formatter or linter — don't comment on style unless it
  creates a clarity or maintenance problem.
- It is not a performance profiler — the Economy principle favors programmer
  time over machine time; don't optimize prematurely.
- It does not mandate UNIX-like tools or bash — the philosophy applies equally
  to a Python library, a Go service, or a React component.
- It is not dogma. Principle 16 (Diversity) is itself a UNIX principle. If the
  user has a good reason to break a rule, acknowledge it.

