Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Find root causes through a structured debugging process instead of guessing, patching, and hoping.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
defense-in-depth.md
1# Defense-in-Depth Validation23## Overview45When you fix a bug caused by invalid data, adding validation at one place feels sufficient. But that single check can be bypassed by different code paths, refactoring, or mocks.67**Core principle:** Validate at EVERY layer data passes through. Make the bug structurally impossible.89## Why Multiple Layers1011Single validation: "We fixed the bug"12Multiple layers: "We made the bug impossible"1314Different layers catch different cases:15- Entry validation catches most bugs16- Business logic catches edge cases17- Environment guards prevent context-specific dangers18- Debug logging helps when other layers fail1920## The Four Layers2122### Layer 1: Entry Point Validation23**Purpose:** Reject obviously invalid input at API boundary2425```typescript26function createProject(name: string, workingDirectory: string) {27if (!workingDirectory || workingDirectory.trim() === '') {28throw new Error('workingDirectory cannot be empty');29}30if (!existsSync(workingDirectory)) {31throw new Error(`workingDirectory does not exist: ${workingDirectory}`);32}33if (!statSync(workingDirectory).isDirectory()) {34throw new Error(`workingDirectory is not a directory: ${workingDirectory}`);35}36// ... proceed37}38```3940### Layer 2: Business Logic Validation41**Purpose:** Ensure data makes sense for this operation4243```typescript44function initializeWorkspace(projectDir: string, sessionId: string) {45if (!projectDir) {46throw new Error('projectDir required for workspace initialization');47}48// ... proceed49}50```5152### Layer 3: Environment Guards53**Purpose:** Prevent dangerous operations in specific contexts5455```typescript56async function gitInit(directory: string) {57// In tests, refuse git init outside temp directories58if (process.env.NODE_ENV === 'test') {59const normalized = normalize(resolve(directory));60const tmpDir = normalize(resolve(tmpdir()));6162if (!normalized.startsWith(tmpDir)) {63throw new Error(64`Refusing git init outside temp dir during tests: ${directory}`65);66}67}68// ... proceed69}70```7172### Layer 4: Debug Instrumentation73**Purpose:** Capture context for forensics7475```typescript76async function gitInit(directory: string) {77const stack = new Error().stack;78logger.debug('About to git init', {79directory,80cwd: process.cwd(),81stack,82});83// ... proceed84}85```8687## Applying the Pattern8889When you find a bug:90911. **Trace the data flow** - Where does bad value originate? Where used?922. **Map all checkpoints** - List every point data passes through933. **Add validation at each layer** - Entry, business, environment, debug944. **Test each layer** - Try to bypass layer 1, verify layer 2 catches it9596## Example from Session9798Bug: Empty `projectDir` caused `git init` in source code99100**Data flow:**1011. Test setup → empty string1022. `Project.create(name, '')`1033. `WorkspaceManager.createWorkspace('')`1044. `git init` runs in `process.cwd()`105106**Four layers added:**107- Layer 1: `Project.create()` validates not empty/exists/writable108- Layer 2: `WorkspaceManager` validates projectDir not empty109- Layer 3: `WorktreeManager` refuses git init outside tmpdir in tests110- Layer 4: Stack trace logging before git init111112**Result:** All 1847 tests passed, bug impossible to reproduce113114## Key Insight115116All four layers were necessary. During testing, each layer caught bugs the others missed:117- Different code paths bypassed entry validation118- Mocks bypassed business logic checks119- Edge cases on different platforms needed environment guards120- Debug logging identified structural misuse121122**Don't stop at one validation point.** Add checks at every layer.123