β All skills
pragmatic-programmer
Use when reviewing architecture, evaluating build-vs-buy, or discussing technical debt and estimation. Applies Pragmatic Programmer principles: DRY, orthogonality, tracer bullets, design by contract.
About this skill
Use when reviewing architecture, evaluating build-vs-buy, or discussing technical debt and estimation. Applies Pragmatic Programmer principles: DRY, orthogonality, tracer bullets, design by contract.
SKILL.md
pragmatic-programmer.SKILL.mdPlace it in your Syntic skills folder. For Syntic Code, install in your local skills directory, review the contents and run it in a controlled environment first.
---
name: pragmatic-programmer
description: Use when reviewing architecture, evaluating build-vs-buy, or discussing technical debt and estimation. Applies Pragmatic Programmer principles: DRY, orthogonality, tracer bullets, design by contract.
category: Business Knowledge
version: 1.0.0
tools: []
---
# The Pragmatic Programmer Framework
A systems-level approach to software craftsmanship from Hunt & Thomas's *The Pragmatic Programmer* (20th Anniversary Edition) -- how to think about software, not just how to write it.
## Core Principle
Care about your craft. Pragmatic programmers think beyond the immediate problem to context, trade-offs, and long-term consequences. Great software comes from great habits: avoid duplication ruthlessly, keep components orthogonal, treat every line of code as a living asset that must earn its place. The goal is not perfection -- it's systems that are easy to change, understand, and trust.
## Scoring
**Goal: 10/10.** Score against the seven Quick Diagnostic rows: ~1.4 points per "yes" (7 yes = 10). **9-10** = every principle holds -- DRY knowledge, orthogonal layers, a working tracer slice, contracts at boundaries, no broken windows, reversible vendor/DB choices, ranged estimates. **5-6** = 1-2 violations that cost real change-effort (e.g. business logic coupled to the DB, single-point estimates). **<=3** = pervasive duplication, global state, or accumulated broken windows -- entropy is winning.
## The Seven Meta-Principles
### 1. DRY (Don't Repeat Yourself)
Every piece of knowledge must have a single, unambiguous, authoritative representation. DRY is about knowledge, not code -- duplicated logic, business rules, or configuration are more dangerous than duplicated syntax. Four types of duplication: imposed, inadvertent, impatient, inter-developer. Comments that restate the code violate DRY -- explain *why*, not *what*. The opposite of DRY is WET ("Write Everything Twice"). Pattern: one JSON Schema or Zod schema shared by client and server, not two.
### 2. Orthogonality
Two components are orthogonal if changes in one don't affect the other. Ask: "If I dramatically change the requirements behind a function, how many modules are affected?" The answer should be one. Layered architectures (presentation, domain logic, data access) promote orthogonality; avoid global data, since every consumer is coupled to it. Pattern: dependency injection -- pass a `Notifier` interface, not a concrete `SlackClient`.
### 3. Tracer Bullets and Prototypes
**Tracer bullets** are thin, end-to-end implementations connecting every layer of the system with minimal functionality -- production code you keep. **Prototypes** are throwaway explorations of a single risky aspect. Use tracer bullets when "shooting in the dark" (vague requirements, unproven architecture); if a tracer misses, adjust and fire again since iteration is cheap. Label prototypes clearly as throwaway -- never let one become production code.
### 4. Design by Contract and Assertive Programming
Define and enforce the rights and responsibilities of modules: **preconditions** (what must be true before, caller's responsibility), **postconditions** (what's guaranteed after), **invariants** (what's always true, e.g. "account balance never goes negative"). When a contract is violated, fail immediately and loudly -- dead programs tell no lies. Use assertions for things that should never happen; error handling for things that might.
### 5. The Broken Window Theory
One broken window -- a badly designed piece of code, a poor decision, a "we'll fix later" hack -- starts the rot; once a system shows neglect, entropy accelerates and discipline collapses. When code is clean, developers keep it that way; when it's already messy, the threshold for adding more mess drops to zero. If you can't fix it now, board it up: a TODO with a ticket, a disabled feature, a stub. The first hack is the most expensive because it gives permission for every hack after it.
### 6. Reversibility and Flexibility
There are no final decisions. Build systems that make it easy to change your mind about databases, frameworks, vendors, architecture, and deployment targets -- the cost of change should be proportional to the scope of change. Abstract third-party dependencies behind your own interfaces; never let vendor APIs leak into business logic. The "forking road" test: could you switch from Postgres to DynamoDB in a week? If not, you're coupled. YAGNI applies to premature abstraction too -- don't build flexibility you don't need yet. Pattern: repository pattern (business logic calls `repo.save(user)`, not `pg.query(...)`) and feature flags for runtime toggles.
### 7. Estimation and Knowledge Portfolio
Estimate reliably by understanding scope, building models, decomposing into components, and assigning ranges. Use **PERT**: (Optimistic + 4 x Most Likely + Pessimistic) / 6. Decompose into components and estimate each -- the sum beats a single guess. Keep an estimation log comparing estimates to actuals. Manage your learning like a financial portfolio: invest regularly (learn weekly), diversify beyond your stack, mix safe and speculative bets, learn emerging tech early (buy low). Honest ranged estimates ("1-3 weeks") build more trust than a confidently wrong single number.
## Code Applications by Principle
| Principle | Pattern | Example |
|-----------|---------|---------|
| DRY | Single source of truth | DB connection in one env file, referenced everywhere |
| Orthogonality | Isolated unit tests | Test business logic without database, network, or filesystem |
| Tracer bullets | Walking skeleton | Hello-world service through the full CI/CD pipeline |
| Contracts | API boundary validation | Validate request body against schema before processing |
| Broken windows | Debt budget | Allocate 20% of each sprint to fixing broken windows |
| Reversibility | Adapter/wrapper | `PaymentGateway` interface wraps Stripe; swap to Braintree later |
## Common Mistakes
| Mistake | Why It Fails | Fix |
|---------|-------------|-----|
| DRY-ing similar-looking code that serves different purposes | Couples unrelated concepts; changes to one break the other | Only DRY knowledge, not coincidental code similarity |
| Skipping tracer bullets, building layer-by-layer | Integration issues surface late; no end-to-end feedback | Build one thin vertical slice first |
| Ignoring broken windows "because we'll refactor later" | Entropy accelerates; later never comes; morale drops | Fix immediately or board up with a tracked ticket |
| Estimates as single-point commitments | False precision erodes trust when missed | Always give ranges with confidence levels |
| Making everything "flexible" upfront | Over-engineering; abstraction without evidence of need | Add flexibility when you have concrete evidence you'll need it |
| Removing production assertions "for performance" | Bugs assertions would catch now surface as corrupted data in production | Keep assertions in production; disable only after profiling proves the cost |
## Portfolio and Estimation Practices
Estimation context changes precision: a budget-planning estimate and a sprint-planning estimate for the same task should look different. Always ask "what is this estimate for?" before committing to a number. Knowledge portfolio rules mirror financial ones: invest regularly (learn weekly, not in binges), diversify beyond your current stack, balance safe bets (your core language) against speculative ones (an emerging framework), and review/rebalance periodically as the market for skills shifts.
## Quick Diagnostic
Does each piece of knowledge live in exactly one place? Could you change the DB or a vendor without touching business logic? Does a thin, working slice already run end-to-end? Are preconditions/postconditions/invariants enforced at module boundaries? Are broken windows fixed immediately or tracked, never ignored? Are vendor/framework choices behind an interface you control? Do estimates carry a range and confidence level, not a single number?
Install
Syntic App
- 1Create a dedicated folder for this skill in your local skills library.
- 2Place SKILL.md into that folder.
- 3Restart Syntic and invoke this skill on matching tasks.
Syntic Code (CLI)
- 1Save SKILL.md in your local Syntic Code skills directory.
- 2Keep related files in the same skill folder.
- 3Run in a safe environment and validate outputs.