# Review Design

> >

- **Type:** Skill
- **Install:** `agentstack add skill-urmzd-dotfiles-review-design`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [urmzd](https://agentstack.voostack.com/s/urmzd)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** Apache-2.0
- **Upstream author:** [urmzd](https://github.com/urmzd)
- **Source:** https://github.com/urmzd/dotfiles/tree/main/dot_agents/skills/review-design

## Install

```sh
agentstack add skill-urmzd-dotfiles-review-design
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Pragmatic Programming

> **Layering:** Principles layer above `assess-quality` (foundational framework) and are operationalized by `write-code` (tool/pattern picks). Use this skill when reasoning about *why* a design tradeoff matters; use `assess-quality` for the underlying quality framework; use `write-code` for concrete picks.

Principles from *The Pragmatic Programmer* (Hunt & Thomas) distilled into actionable rules for everyday development.

## Core Philosophy

- **Care about your craft** why spend your life developing software unless you care about doing it well?
- **Think critically** question assumptions, challenge "because we've always done it that way"
- **Be a catalyst for change** show people a future they can rally around (stone soup)
- **Remember the big picture** don't get so absorbed in details that you forget the system as a whole (boiling frog)
- **Good enough software** know when to stop; perfect is the enemy of shipped

## ETC: Easy to Change

The fundamental design principle. Every decision should make future change easier.

- When choosing between approaches, pick the one that's easier to change later
- If you can't decide which path is more changeable, fall back on: make it replaceable
- Decoupled code is easier to change; single-responsibility code is easier to change; well-named code is easier to change. ETC is the *why* behind all of them

## DRY: Don't Repeat Yourself

> Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.

| Violation | Fix |
|-----------|-----|
| Copy-pasted logic | Extract shared function/module |
| Knowledge in code AND comments | Let code be the authority; remove redundant comments |
| Same validation in client and server | Single schema, generate both |
| Repeated config across environments | Template or derive from one source |
| Data structure duplicated across types | Single source type, derive others |

- DRY applies to **knowledge**, not text. Two functions with identical code but representing different knowledge are not DRY violations
- Watch for DRY violations across: code, documentation, data schemas, API specs, build config

## Orthogonality

Keep components independent. Changes in one should not affect others.

- **Test:** If I change X, how many other things must also change? Aim for zero
- Eliminate effects between unrelated things
- Avoid global/shared mutable state
- Prefer composition over inheritance
- Shy code: modules that don't reveal anything unnecessary and don't rely on other modules' implementations

## Reversibility

- Don't commit to a single vendor, platform, database, or architecture prematurely
- Abstract external dependencies behind interfaces
- Prefer configuration over hard-coding
- No critical decisions should be irreversible. If they must be, document and isolate them

## Tracer Bullets

Build thin, end-to-end slices that work, then iterate.

- First version connects all layers (UI to DB) with minimal functionality
- Proves the architecture works, reveals integration problems early
- Different from prototypes: tracer bullet code is kept and built upon
- Use when: requirements are vague, risk is high, or the team hasn't used the stack before

## Prototypes

- Prototype to **learn**, then throw away the code
- Prototypes can ignore: correctness, completeness, robustness, style
- Make it absolutely clear to stakeholders that prototype code is disposable
- Prototype when exploring: architecture, new libraries, UI design, performance approaches

## Estimation

| Duration | Quote in |
|----------|----------|
| 1-15 days | days |
| 3-6 weeks | weeks |
| 8-20 weeks | months |
| > 20 weeks | re-scope before estimating |

- Build a model of the system, identify driving parameters, calculate
- Track your estimates vs. actuals to improve over time
- When asked for an estimate you're not ready to give: "I'll get back to you"

## Design by Contract

- Define **preconditions** (what must be true before), **postconditions** (what's guaranteed after), and **class invariants**
- Crash early. A dead program does less damage than a crippled one
- Use assertions liberally for invariants; don't use them for normal error handling
- Lazy code: be strict in what you accept, promise as little as possible in return

## Pragmatic Paranoia

- **You can't write perfect software** design assuming your code will fail
- Crash early rather than propagate bad state
- Use `try/finally` or equivalent to guarantee resource cleanup
- Assert aggressively. Leave assertions on in production when cost is low
- Don't assume; prove it with assertions and tests

## Decoupling & the Law of Demeter

- **Tell, Don't Ask** tell objects what to do, don't query state and decide for them
- **Law of Demeter** a method should only call methods on: itself, its parameters, objects it creates, its direct fields
- Avoid train wrecks: `a.b().c().d()`. Each dot is a coupling point
- Use events/pub-sub to decouple temporal and structural dependencies
- Prefer: pass in what you need (dependency injection) over reaching out to get it (service locator)

## Transforming Programming

- Think of programs as **data transformations** input -> pipeline of steps -> output
- Prefer pipelines of small transforms over stateful methods that mutate objects
- `|>` thinking: each step takes data, returns transformed data
- Reduces coupling, improves testability, makes data flow visible

## Refactoring

- Refactor **early and often** don't let technical debt compound
- Don't live with **broken windows** fix bad code, bad design, and poor decisions as soon as you see them
- Refactor when you learn something new, not on a schedule
- Disciplined refactoring: keep behavior identical, test before and after, take small steps

## Testing

For per-language conventions, test types, and CI strategy, see the `test-code` skill.

- **Test your software, or your users will**
- Test state coverage, not code coverage. Exercise meaningful paths, not just lines
- Use **property-based testing** to discover edge cases you didn't think of
- Build a test window: logging, diagnostics, hot-key status that lets you peer inside running code
- Test against contract (what it should do), not implementation (how it does it)
- Unit tests are the first users of your API. If tests are hard to write, the design is wrong

## Naming

- A good name captures **intent**, not implementation (`processedItems` not `list2`)
- Name length should be proportional to scope. Short in small lambdas, descriptive in public APIs
- Rename when the name no longer fits. Outdated names are worse than no name
- Naming conventions are a team contract; follow them consistently

## Power of Plain Text

- Keep knowledge in plain text where possible. It outlives all applications
- Config, data formats, build scripts: prefer human-readable formats
- Plain text is self-describing, easier to test, easier to diff, and version-control friendly

## Domain Languages

- Write code in the vocabulary of the problem domain, not the solution domain
- Internal DSLs (fluent APIs, builder patterns) reduce the gap between spec and code
- When the same concept appears repeatedly in different forms, consider whether a mini-language would simplify things

## Pragmatic Teams

- **No broken windows** quality is a team responsibility, not an individual one
- Automate everything: builds, tests, deployments, code formatting
- **Don't outrun your headlights** take small steps, get frequent feedback
- Schedule time to work ON the project (tooling, process), not just IN it

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [urmzd](https://github.com/urmzd)
- **Source:** [urmzd/dotfiles](https://github.com/urmzd/dotfiles)
- **License:** Apache-2.0

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-urmzd-dotfiles-review-design
- Seller: https://agentstack.voostack.com/s/urmzd
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
