ryanthedev/code-foundations/cc-defensive-programming

Claude Code and agent skill by ryanthedev/code-foundations

Trust tier 2
  • community
LLM review pending
Source check pending

Checking that the SKILL.md file is still in the repository.

Applies Code Complete's defensive programming rules: barricade design, assertion vs error-handling selection, input validation policy, and correctness-vs-robustness strategy for the current context. For hardening code at trust boundaries; not for diagnosing an active failure (use cc-debugging) or post-completion verification (use aposd-verifying-correctness).

Install

npx vskill@latest install ryanthedev/code-foundations/cc-defensive-programming

SKILL.md

cc-defensive-programming

Defensive code keeps small failures from compounding into silent, hard-to-diagnose ones. These four checks catch the violations that corrupt data and hide bugs rather than crashing loudly — each is almost always required; exceptions need explicit justification:

CheckWhy
No executable code in assertionsAssertions are compiled out of production builds; the code vanishes with them
No empty catch blocksSilently swallows bugs that cascade into harder failures downstream
External input validated at entryUnvalidated input is security vulnerabilities and data corruption
Assertions for bugs onlyAnticipated runtime errors need handling, not assertions (which are disabled in production)

Two rules that override the textbook

  • "Internal team API" is still external. Any data crossing a network or process boundary is external input — validate it, even from a service your own team owns.
  • A barricade reduces redundant validation; it does not replace defense-in-depth. Inside the barricade you may assume data is validated — except for security-critical paths (auth, crypto, PII), where you validate again. Barricade validation has bugs too.

External input = any data not provably controlled by the current code path: user input, files, network/API/DB responses, environment variables, and data from any other service.

When NOT to apply

  • Pure functions without side effects (but still validate inputs at system boundaries).
  • Prototype/spike code, time-boxed before committing to an error strategy.
  • Test code — test doubles intentionally violate production patterns.
  • Performance-critical inner loops where assertion overhead is profiled at >5%.

Security-critical code (authentication, authorization, cryptographic operations, PII handling) is never exempt, regardless of the above. When in doubt, validate.

Modes

CHECKER

Execute the defensive-programming, assertion, and exception checklists against the code: Read(${CLAUDE_SKILL_DIR}/checklists.md). VIOLATION = missing validation, empty catch, side-effecting assertion; WARNING = inconsistent handling, missing docs. CHECKER output: the ID'd checklist is the item set (the tables in this SKILL.md explain the items, they are not counted twice). Report each VIOLATION and WARNING as | Item | Status | Evidence | Location |; do not list passing or non-applicable items — close with one line N items checked, M pass, K n/a.

APPLIER

Produce assertion placement, error-handling strategy, barricade architecture, and validation implementations. Search the codebase for the existing error-handling pattern (exception vs return code vs Result type, custom exception classes, logging conventions) and follow it — consistency in error handling is what makes failures debuggable.

Assertion vs error handling

ConditionAssertionError handling
Should never occur (programmer bug)YesNo
Can occur at runtime / anticipated bad inputNoYes
External inputNoYes — always validate
Internal interface, same moduleYesNo
Internal interface crossing a trust boundaryYesYes
Public-API precondition violationYesYes
Security-critical / highly robust systemBothBoth (defense in depth)

When a condition is genuinely unclear ("is this a bug or expected?"), clarify requirements with a domain expert rather than guessing.

Correctness vs robustness

  • Correctness — never return an inaccurate result; shut down rather than produce a wrong answer (safety-critical, financial, data pipelines).
  • Robustness — keep operating even if results are sometimes inaccurate (consumer apps, internal tools).
DomainLean towardKey question
Safety-critical (medical, aviation)Correctness—
Enterprise/B2B, financial, data pipelinesCorrectnessWould wrong data drive a bad business decision? Does downstream assume integrity?
SaaS platformsBalancedBlast radius of a wrong answer vs unavailability?
Consumer apps, internal toolsRobustnessCan the user recover from a crash?
Real-time systemsContext-dependentIs stale data better or worse than no data?

Barricade design

  1. Identify external interfaces (user input, files, network, APIs, inter-service calls).
  2. Place validation at the barricade boundary — all external data checked here.
  3. Inside the barricade, use assertions for internal bugs (data assumed validated).
  4. Strategy: external boundary = error handling; internal = assertions.

Class-level barricade: public methods validate and sanitize; private methods within that class may assume safe data.

Error-handling strategy options

Choose one and apply it consistently — error handling is an architectural decision.

StrategyUse for
Return neutral valueDisplay defaults, non-critical config
Substitute next valid dataStreaming/sensor data with redundancy
Return previous answerDisplay refresh, non-critical caching (never financial data)
Substitute closest legal valueInput clamping, slider bounds
Log warning and continueNon-critical degradation, feature flags
Return error codeAPIs with status conventions, C-style interfaces
Centralized error handlerConsistent logging, monitoring integration
Display error messageUser-facing apps (don't leak security info)
Shut down gracefullySafety-critical, data-corrupting errors

Modern error propagation

Synchronous exception propagation assumes a synchronous call stack; these patterns need explicit handling:

  • async/await — an unhandled rejection crashes Node; wrap awaited calls and re-throw domain-level exceptions.
  • Callbacks — errors don't propagate; use the error-first callback(error, result) pattern or wrap in promises.
  • `Promise.all` — first rejection loses other results; use allSettled and decide fail-entirely vs partial.
  • Event handlers / React — synchronous throws are silently swallowed; log explicitly and use error boundaries for render errors.

Offensive programming (development builds)

Make errors loud during development so they're found early; make them unobtrusive with graceful recovery in production. Techniques: make asserts abort, fill allocated memory and freed objects with junk, fail hard on default/else clauses, email error logs to yourself.

Security

  • Security scanPassed, 82 of 100Pattern checks on the skill's files.
  • Model reviewNot runA model review is scheduled for the next rescan.

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
172
Repository forks
15
7-day trend score
26

Stars and forks are for the whole GitHub repository, not this skill alone. Refreshed 20 Mar 2026, 7 months ago.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/ryanthedev/code-foundations/cc-defensive-programming/badge)](https://verified-skill.com/skills/ryanthedev/code-foundations/cc-defensive-programming)

Something wrong with this skill or its page? Tell us.