incremental-verified-implementation
verified4f767999-9e03-4311-8b41-284196dc0617
Implement in the smallest possible working slice, then verify each slice with a test or a run before moving on. Use for any non-trivial implementation to avoid big-bang breakage.
Metadata
Skill file
# Incremental Verified Implementation
Use for any non-trivial implementation — a new feature, a refactor, a bug fix that
touches more than one line. The discipline: make the smallest change that moves the
needle, verify it with a focused check, and commit (or revert). Never batch
unrelated edits.
## 1. The slice loop
```
while not done:
change = smallest_meaningful_edit()
verify(change) # single focused check
if check passes:
git commit
else:
git restore . # revert, then shrink the change
```
A "meaningful edit" is a change that leaves the tree in a working state and moves
one leaf of the decomposition forward. It is typically:
- One new function + one test calling it
- One new endpoint route + one `curl` verification
- One schema change + one migration run
- One bug fix + the repro test that now passes
## 2. What "verify" means per language
| Language / stack | Focused verify command |
|---|---|
| Python (pytest) | `pytest tests/test_<module>.py -k <specific_test>` |
| Python (script) | `python path/to/script.py` + check exit code |
| Go | `go test ./path/to/package -run TestName` |
| Node.js | `npx jest --testPathPattern=filename -t "test name"` |
| Rust | `cargo test test_name` |
| SQL | `psql -f migration.sql -c 'SELECT ...'` |
| Shell / config | `diff <(./script.sh) <(expected_output)` or `shellcheck` |
The rule: run the smallest scope that covers your change. Running the full suite
for a one-line edit is noise; running nothing is negligence.
## 3. Keeping the tree green
Every commit must pass the focused check. This ensures:
```bash
# Bisectability: every commit is a possible "good" or "bad" boundary
git bisect start
git bisect bad HEAD
git bisect good v2.0
# git automatically runs the test at each step — if any commit fails,
# bisection is unreliable
```
A green tree at every commit means `git bisect` works, `git revert` is safe, and
you never lose work debugging a pile of uncommitted broken changes.
## 4. When a slice fails
If the focused check fails:
1. **Revert immediately** — `git restore .` or `git stash`
2. **Shrink the change** — smaller slice, smaller scope
3. **Re-attempt** with the smaller slice
The alternative — "I'll just add another fix on top" — leads to the big-bang
debugging death spiral: 5 broken things layered on 3 broken things, and you cannot
tell which caused what.
## 5. Recognizing when to commit
| Situation | Action |
|---|---|
| Focused check passes, no unrelated side effects | `git commit -m "<slice description>"` |
| Check passes but you see unrelated breakage | Revert, fix the unrelated issue first |
| Check fails | Revert, shrink the slice |
| You made 3 unrelated edits in one slice | Separate into 3 slices now, not later |
## 6. Worked example: a feature in 5 slices
Implementing "add a `slugify` util" slice by slice:
```text
Slice 1: create src/utils/slugify.py with the function signature + docstring,
raise NotImplementedError for now.
verify: python -c "import src.utils.slugify" # imports clean
commit: "Add slugify util skeleton"
Slice 2: implement the happy path (lowercase + replace spaces with hyphens).
verify: pytest tests/test_slugify.py -k test_basic
commit: "Implement slugify happy path"
Slice 3: handle edge cases (empty string, unicode, leading/trailing dashes).
verify: pytest tests/test_slugify.py -k test_edge
commit: "Handle slugify edge cases"
Slice 4: wire it into the caller (replace the inline version).
verify: pytest tests/test_article.py -q # caller still green
commit: "Use slugify util in article model"
Slice 5: docstring + remove the now-dead inline helper.
verify: ruff check && pytest -q
commit: "Document slugify, remove dead inline helper"
```
Notice each slice has one commit, one focused verify, and never leaves the tree
broken. Notice also slice 1 deliberately leaves a `NotImplementedError` — but it
is filled in by slice 2 *before* the feature is ever called "done" (see
complete-code-no-stubs for why a shipped `NotImplementedError` is a bug).
## 7. How this differs from strict TDD
- **TDD** writes the failing test first, then the minimal code to pass.
- **Slice loop** makes the smallest *change* first, then verifies with a test/run.
They overlap heavily but the slice loop also covers refactors, config changes, and
scripting work where a test-first contract is impractical. Use whichever fits; the
non-negotiable part is *verify every slice*.
## Guardrails
- Do **not** implement the whole feature, then debug it all at once. The "one big
push" is the leading cause of lost hours and unmergable branches.
- Do **not** skip verification on "trivial" edits. Most regressions come from a
one-line "obvious" change.
- Do **not** use "it compiles" as verification for dynamic languages. Compilation
is not correctness.
- Do commit after every successful slice. Uncommitted work cannot be bisected or
reverted cleanly.
- Do keep slices truly small — if your commit message needs a paragraph, the slice
is too big.
## Pitfalls
- **"It compiles, so it works"** — type-checking or compilation catches a subset
of bugs. Run the focused test anyway.
- **Skipping verification on trivial edits** — a one-line "cleanup" that breaks
a dependent module is routine.
- **Big-bang implementation** — writing 500 lines, running tests, and getting 12
failures you cannot disentangle.
- **Committing broken slices** — "I'll fix it in the next commit" destroys
bisectability.
- **Over-verifying** — running the full 10-minute test suite after renaming a local
variable is ceremony, not discipline.
## Verify / Checklist
- [ ] Every implementation session follows the slice loop: change → verify → commit or revert.
- [ ] The focused check is appropriate for the language/stack and runs in < 30 seconds.
- [ ] The tree is green (all tests pass) at every commit in `git log`.
- [ ] No commit contains unrelated changes — each commit message describes one slice.
- [ ] Failed slices are reverted, not patched on top.
- [ ] `git bisect` could be run against the branch without false positives.
Attached files
No attached files.