pragmatic-programmer — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited pragmatic-programmer (Agent Skill) and scored it 96/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 1 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 1 flagged
The text {match} tells the agent to skip the normal "ask the user first" gate. Used adversarially it removes the human-in-the-loop check before destructive or sensitive actions, turning a normally-gated agent into a fire-and-forget executor.
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
A systems-level approach to software craftsmanship from Hunt & Thomas' "The Pragmatic Programmer" (20th Anniversary Edition). Apply these meta-principles when designing systems, reviewing architecture, writing code, or advising on engineering culture -- how to think about software, not just how to write it.
Care about your craft. Software development demands continuous learning, disciplined practice, and personal responsibility -- 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, and treat every line of code as a living asset that must earn its place. The goal is not perfection -- it is systems that are easy to change, easy to understand, and easy to trust.
Goal: 10/10. Rate software designs, architecture, or code 0-10 based on adherence to the principles below; a 10/10 means full alignment, lower scores indicate gaps to address. Always state the current score and the specific improvements needed to reach 10/10.
Seven meta-principles for building software that lasts:
Core concept: Every piece of knowledge must have a single, unambiguous, authoritative representation within a system. DRY is about knowledge, not code -- duplicated logic, business rules, or configuration are far more dangerous than duplicated syntax.
Why it works: Duplicated knowledge must be changed in multiple places; eventually one gets missed, introducing inconsistency. DRY reduces the surface area for bugs and makes systems easier to change.
Key insights:
Code applications:
| Context | Pattern | Example |
|---|---|---|
| Config values | Single source of truth | DB connection in one env file, referenced everywhere |
| Validation rules | Shared schema | One JSON Schema or Zod schema for client and server |
| API contracts | Generate from spec | OpenAPI spec generates types, docs, and client code |
See: references/dry-orthogonality.md for the four duplication types and orthogonal design in depth.
Core concept: Two components are orthogonal if changes in one do not affect the other. Design systems where components are self-contained, independent, and have a single, well-defined purpose.
Why it works: Orthogonal systems are easier to test, easier to change, and produce fewer side effects. Change the database layer and the UI should not break; change the auth provider and business logic should not care.
Key insights:
Code applications:
| Context | Pattern | Example |
|---|---|---|
| Architecture | Layered separation | Controller -> Service -> Repository, each replaceable |
| Dependencies | Dependency injection | Pass a Notifier interface, not a SlackClient concrete class |
| Testing | Isolated unit tests | Test business logic without database, network, or filesystem |
Core concept: Tracer bullets are end-to-end implementations connecting all layers of the system with minimal functionality. Unlike prototypes (which are throwaway), tracer bullet code is production code -- thin but real.
Why it works: Tracer bullets give immediate end-to-end feedback before you invest in filling out every feature. Users see something real, developers have a framework to build on, and integration issues surface early.
Key insights:
Code applications:
| Context | Pattern | Example |
|---|---|---|
| New project | Vertical slice | One feature end-to-end: button -> API -> DB -> response |
| Uncertain tech | Spike prototype | Test WebSocket performance before committing |
| Microservice | Walking skeleton | Hello-world service through the full CI/CD pipeline |
See: references/tracer-bullets.md for tracer vs. prototype decisions and walking skeletons.
Core concept: Define and enforce the rights and responsibilities of software modules through preconditions (what must be true before), postconditions (what is guaranteed after), and invariants (what is always true). When a contract is violated, fail immediately and loudly.
Why it works: Contracts make assumptions explicit. Instead of silently corrupting data or limping along in an invalid state, the system crashes at the point of the problem -- dead programs tell no lies.
Key insights:
Code applications:
| Context | Pattern | Example |
|---|---|---|
| Function entry | Precondition guard | assert age >= 0, "Age cannot be negative" at function start |
| Class state | Invariant validation | validate! called after every state mutation |
| API boundary | Schema validation | Validate request body against schema before processing |
See: references/contracts-assertions.md for contract patterns and assertive programming.
Core concept: One broken window -- a badly designed piece of code, a poor management decision, a hack that "we'll fix later" -- starts the rot. Once a system shows neglect, entropy accelerates and discipline collapses.
Why it works: Psychology. When code is clean, developers feel social pressure to keep it that way; when code is already messy, the threshold for adding more mess drops to zero. Quality is a team habit, not an individual heroic effort.
Key insights:
Code applications:
| Context | Pattern | Example |
|---|---|---|
| Legacy code | Board up windows | Wrap bad code in a clean interface before adding features |
| Code review | Zero-tolerance for new debt | Reject PRs adding // TODO: fix later without a ticket |
| Tech debt | Debt budget | Allocate 20% of each sprint to fixing broken windows |
See: references/broken-windows.md for entropy fighting and the stone soup strategy.
Core concept: 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.
Why it works: Requirements change, vendors get acquired, technologies fall out of favor. If your architecture hard-codes assumptions about any of these, every change becomes a rewrite; flexible architecture treats decisions as configuration, not structure.
Key insights:
Code applications:
| Context | Pattern | Example |
|---|---|---|
| Database | Repository pattern | Business logic calls repo.save(user), not pg.query(...) |
| External API | Adapter/wrapper | PaymentGateway interface wraps Stripe; swap to Braintree later |
| Feature flags | Runtime toggles | New checkout flow behind a flag, rollback in seconds |
See: references/reversibility.md for decoupling strategies and avoiding vendor lock-in.
Core concept: Learn to estimate reliably by understanding scope, building models, decomposing into components, and assigning ranges. Manage your learning like a financial portfolio: invest regularly, diversify, and rebalance.
Why it works: Honest estimation builds trust with stakeholders ("1-3 weeks" beats a confidently wrong "2 weeks"). A knowledge portfolio keeps you relevant as technologies shift -- the programmer who stops learning stops being effective.
Key insights:
Code applications:
| Context | Pattern | Example |
|---|---|---|
| Sprint planning | Range estimates | "3-5 days" with confidence level, not a single number |
| New technology | Time-boxed spike | "2 days evaluating; then I can estimate properly" |
| Learning | Weekly investment | 1 hour/week on a new language, tool, or domain |
See: references/estimation-portfolio.md for PERT and portfolio management.
| 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 silently corrupt data | Keep critical assertions; benchmark before removing any |
| Global state "for convenience" | Destroys orthogonality; everything coupled to everything | Use dependency injection and explicit parameters |
| Question | If No | Action |
|---|---|---|
| Can I change the database without touching business logic? | Orthogonality violation | Introduce repository/adapter pattern |
| Do I have an end-to-end slice working? | Missing tracer bullet | Build one vertical slice before expanding |
| Is every business rule defined in exactly one place? | DRY violation | Identify the authoritative source; remove duplicates |
| Would a new developer call this codebase "clean"? | Broken windows present | Schedule a dedicated cleanup sprint |
| Do my estimates include ranges and confidence levels? | Estimation problem | Switch to PERT or range-based estimates |
| Can I roll back this deployment in under 5 minutes? | Reversibility gap | Add feature flags and blue-green deploys |
| Am I learning something new every week? | Knowledge portfolio stagnant | Schedule weekly learning time and track it |
Andrew Hunt and David Thomas co-founded the Pragmatic Bookshelf and were among the 17 original authors of the Agile Manifesto. Thomas coined "DRY" and "Code Kata" and co-authored Programming Ruby (the Pickaxe book); Hunt focuses on how teams learn, communicate, and maintain quality. Together they wrote The Pragmatic Programmer, one of the most influential software books ever published.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.