From claudekit
Applies defense-in-depth by enforcing validation at multiple layers—entry points, business logic, environment guards—to prevent data integrity bugs and recurrence after failures.
npx claudepluginhub duthaho/claudekit --plugin claudekitThis skill uses the workspace's default tool permissions.
- After fixing any data-related bug
Implements defense-in-depth validation across entry points, business logic, environment guards, and debug instrumentation to prevent invalid data failures deep in execution stacks.
Implements defense-in-depth validation across entry points, business logic, environment guards, and debug instrumentation to prevent invalid data causing deep failures.
Applies multi-layer validation—entry points, business logic, environment guards, debug logging—to make invalid data bugs impossible in TypeScript/Node.js code.
Share bugs, ideas, or general feedback.
"Validate at EVERY layer data passes through. Make the bug structurally impossible."
Single validation points can be bypassed:
Multiple layers create redundancy:
Reject invalid input at API/system boundaries:
// API endpoint - first line of defense
app.post('/orders', (req, res) => {
// Type check
if (typeof req.body.userId !== 'string') {
return res.status(400).json({ error: 'userId must be a string' });
}
// Existence check
if (!req.body.userId) {
return res.status(400).json({ error: 'userId is required' });
}
// Format validation
if (!isValidUUID(req.body.userId)) {
return res.status(400).json({ error: 'userId must be a valid UUID' });
}
// Proceed with valid data
orderService.createOrder(req.body);
});
Ensure data semantically makes sense for the operation:
// Service layer - business rules
class OrderService {
async createOrder(data: OrderData) {
// Business validation
const user = await this.userRepo.findById(data.userId);
if (!user) {
throw new BusinessError('User does not exist');
}
if (!user.canPlaceOrders) {
throw new BusinessError('User is not allowed to place orders');
}
if (data.items.length === 0) {
throw new BusinessError('Order must have at least one item');
}
// Proceed with valid business state
return this.orderRepo.create(data);
}
}
Add context-specific safeguards:
// Repository layer - environment guards
class OrderRepository {
async create(order: Order) {
// Test environment guard
if (process.env.NODE_ENV === 'test' && !process.env.ALLOW_DB_WRITES) {
throw new Error('Database writes disabled in test environment');
}
// Production safety guard
if (order.total > 100000 && !order.managerApproval) {
throw new Error('Large orders require manager approval');
}
// Dangerous operation guard
if (order.userId === SYSTEM_USER_ID) {
throw new Error('Cannot create orders for system user');
}
return this.db.insert('orders', order);
}
}
Capture execution context for forensic analysis:
// Logging layer - forensic evidence
class OrderRepository {
async create(order: Order) {
// Log entry for debugging
this.logger.debug('Creating order', {
orderId: order.id,
userId: order.userId,
itemCount: order.items.length,
total: order.total,
timestamp: new Date().toISOString(),
requestId: context.requestId
});
try {
const result = await this.db.insert('orders', order);
this.logger.info('Order created successfully', {
orderId: result.id,
duration: Date.now() - start
});
return result;
} catch (error) {
this.logger.error('Order creation failed', {
orderId: order.id,
error: error.message,
stack: error.stack,
order: JSON.stringify(order)
});
throw error;
}
}
}
// Only one check - easily bypassed
function createOrder(data) {
if (!data.userId) throw new Error('userId required'); // Single check
// ...
}
// Direct repository call bypasses validation
orderRepository.create({ items: [] }); // No userId check!
// Multiple checks - defense in depth
// Layer 1: API validates
// Layer 2: Service validates
// Layer 3: Repository validates
// Even if one is bypassed, others catch it
orderRepository.create({ items: [] });
// Repository throws: "userId is required"
When debugging, use this approach:
User Input → API → Service → Repository → Database
Where does this data pass through?
- API endpoint (Layer 1)
- Service method (Layer 2)
- Repository method (Layer 3)
- Database constraints (Layer 4)
For each checkpoint:
- What could be wrong at this point?
- What validation makes sense here?
- What error message helps debug?
Remove each layer one at a time:
- Does the bug still get caught?
- Which layer catches it?
- Is there a gap in coverage?
| Layer | What to Validate | Example |
|---|---|---|
| Entry Point | Type, format, presence | userId is string, not empty |
| Business Logic | Semantic correctness | User exists, can place orders |
| Environment | Context-specific rules | Test mode restrictions |
| Data Access | Integrity constraints | Foreign keys, not null |
// BAD: One validation point
if (isValid(data)) {
// Assume valid everywhere else
}
// BAD: Tests validate, production doesn't
beforeEach(() => {
validateTestData(data); // This doesn't help production
});
// BAD: Validated once, trusted forever
const validatedData = validate(input);
// ... many lines later ...
process(validatedData); // Is it still valid?
After fixing any bug:
root-cause-tracing - Use before defense-in-depth to find the actual source of the bug before adding multi-layer validationsystematic-debugging - General debugging methodology that pairs with defense-in-depth for comprehensive bug resolutionowasp - Security-specific validation patterns that complement defense-in-depth for security-sensitive code paths