# Hole Driven Development Core

> Use when implementing functions or modules top-down by decomposing into typed holes, filling iteratively from most constrained to least

- Skill: `jhhuh/hole-driven-development-core` (Agent Skill)
- Install (CLI): `npx skillmds@latest add jhhuh/hole-driven-development-core`
- Raw SKILL.md: https://api.skillmd.com/api/skills/jhhuh/hole-driven-development-core/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: jhhuh (https://skillmd.com/u/jhhuh)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/jhhuh/hole-driven-development-core

---


# Hole Driven Development — Core

## Overview

Implement top-down by decomposition. Start with the outermost structure, leave **holes** for unknown parts, then fill each hole iteratively — possibly introducing smaller holes — until none remain.

**Core principle:** Never write a complete implementation in one pass. Decompose first, fill later.

## The Loop

```
1. Receive intention (type signature, spec, or description)
2. Write skeleton to the file with HOLES for each unknown sub-problem
3. Pick the most constrained hole (fewest valid fills)
4. Determine what the hole needs (type, contract, inputs available)
5. Fill ONE hole in the file — introduce sub-holes if the fill is itself complex
6. VERIFY the fill against previously filled code:
   - Shared mutable state: is access synchronized?
   - Lifecycle: are acquire/release scopes matched across holes?
   - Error/cancel paths: do they clean up resources from other holes?
   If any check fails, fix before proceeding.
7. Repeat from 3 until no holes remain
8. REVIEW-ALL: before declaring done, re-read the complete implementation:
   - State transitions that span multiple fills
   - Resource acquired in one fill, released in another
   - Error paths that cross fill boundaries
   - Loop invariants depending on multiple fills
   Fix any systemic bug the per-hole VERIFY could not catch.
```

**Holes must be visible.** Write holes to the file, not just in your reasoning. Each iteration of the loop edits the file — the human should see the skeleton evolve in their editor.

**One hole per iteration.** Fill exactly one hole, then reassess. Do not batch-fill.

**Most constrained first.** When multiple holes exist, fill the one with the narrowest contract — it has the fewest possible implementations, so you're least likely to get it wrong.

**When ambiguous** — multiple equally valid fills — STOP and ask the human.

**When NOT to decompose further.** Some algorithms are inherently monolithic — dual-cursor walks, coroutine-style loops, complex state machines with tightly coupled transitions. If the state cannot be cleanly partitioned across hole boundaries, keep it as a single hole with internal comments for structure rather than splitting into sub-holes that introduce bugs at the seams.

## Success Criterion

No holes remain, the code satisfies the original intention, the REVIEW-ALL pass found no systemic bugs, and no cross-hole interaction bugs remain.

## What This Skill Does NOT Cover

- **How** to determine what a hole needs — that depends on the extending skill:
  - Compiler-feedback loop: `hole-driven-development` (runs compiler, reads diagnostics)
  - Iterative reasoning: `hole-driven-development-iterative-reasoning` (Claude reasons about contracts)

## Red Flags — STOP

- Writing a complete implementation without first creating holes
- Keeping holes in your head instead of writing them to the file
- Filling multiple holes in a single step
- Skipping hole analysis ("I already know the answer")
- Writing the final code directly and claiming you "decomposed mentally"
- Creating artificial decomposition for trivial one-liners (1-2 lines of obvious code)
- Skipping the VERIFY step after filling ("it's obviously correct in context")

**If you catch yourself doing any of these: STOP. Delete. Start with holes in the file.**

