From tk-house-style
Use when invalid data causes failures deep in execution - validates at every layer data passes through to make bugs structurally impossible rather than temporarily fixed
How this skill is triggered — by the user, by Claude, or both
Slash command
/tk-house-style:defense-in-depthThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
When 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.
When 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.
Core principle: Validate at EVERY layer data passes through. Make the bug structurally impossible.
Use when:
Don't use when:
Purpose: Reject invalid input at API/system boundary
function createProject(name: string, workingDirectory: string) {
if (!workingDirectory?.trim()) {
throw new Error('workingDirectory cannot be empty');
}
if (!existsSync(workingDirectory)) {
throw new Error(`workingDirectory does not exist: ${workingDirectory}`);
}
// ... proceed
}
When needed: Always. This is your first line of defense.
Purpose: Ensure data makes sense for this specific operation
function initializeWorkspace(projectDir: string, sessionId: string) {
if (!projectDir) {
throw new Error('projectDir required for workspace initialization');
}
// ... proceed
}
When needed: When business rules differ from entry validation, or when mocks might bypass Layer 1.
Purpose: Prevent dangerous operations in specific contexts
async function gitInit(directory: string) {
if (process.env.NODE_ENV === 'test') {
const normalized = normalize(resolve(directory));
if (!normalized.startsWith(tmpdir())) {
throw new Error(`Refusing git init outside temp dir in tests: ${directory}`);
}
}
// ... proceed
}
When needed: When operation is destructive/irreversible, especially in test environments.
Purpose: Capture context for forensics when other layers fail
async function gitInit(directory: string) {
logger.debug('git init', { directory, cwd: process.cwd(), stack: new Error().stack });
// ... proceed
}
When needed: When debugging is difficult, or when you need to trace how bad data arrived.
| Situation | Layers Needed |
|---|---|
| Public API, simple validation | 1 only |
| Data crosses multiple services | 1 + 2 |
| Destructive operations (delete, init, write) | 1 + 2 + 3 |
| Chasing a hard-to-reproduce bug | 1 + 2 + 3 + 4 |
| Tests mock intermediate layers | At minimum: 1 + 3 |
When you find a bug caused by invalid data:
| Layer | Question It Answers | Typical Check |
|---|---|---|
| Entry | Is input valid? | Non-empty, exists, correct type |
| Business | Does it make sense here? | Required for this operation, within bounds |
| Environment | Is this safe in this context? | Not in prod, inside temp dir, etc. |
| Debug | How did we get here? | Log stack, cwd, inputs |
| Mistake | Fix |
|---|---|
| One validation point, call it done | Add at least entry + business layers |
| Identical checks at adjacent layers | Make each layer check something different |
| Environment guards only in prod | Add them in test too (prevent test pollution) |
| Skipping debug logging | Add it during the bug hunt, keep it |
| Validation but no useful error message | Include the bad value and expected format |
During testing, each layer catches bugs the others miss:
Don't stop at one validation point. The bug isn't fixed until it's impossible.
Provenance: ported from ed3d-plugins/ed3d-house-style (CC-BY-SA-4.0); some skills derive ultimately from obra/superpowers (MIT) or the Trail of Bits skills repo. See repo root LICENSE.
npx claudepluginhub tk-evans01/tk-harness --plugin tk-house-styleProvides behavioral guidelines to reduce common LLM coding mistakes, focusing on simplicity, surgical changes, assumption surfacing, and verifiable success criteria.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.