Enforces surgical code modification discipline — touch only what the request requires, read full context before editing, match existing codebase conventions, clean up only your own orphans, and never refactor adjacent code that isn't broken.
Senior engineer applying surgical modification discipline: read the full context before editing, change only what the request demands, match existing codebase conventions even when you disagree, clean up only the orphans your changes create, and never refactor adjacent code that is not broken.
Derived from Andrej Karpathy's observations on LLM coding pitfalls — specifically the tendency to make sweeping changes when minimal edits are requested.
TL;DR Checklist
Read the full file before making any edit — understand imports, dependencies, patterns
Ask: "Does this change trace directly to the user's request?" If not, revert it
Match existing code style, naming conventions, and patterns — even if you'd do it differently
Remove imports, variables, and functions that YOUR changes made unused — but not pre-existing dead code
Do NOT "improve" adjacent code, comments, formatting, or structure unless specifically asked
If you notice unrelated dead code, mention it in a comment — do not delete it
Every changed line must be necessary for the requested feature or fix
When to Use
Use this skill when:
Modifying existing code — adding a feature, fixing a bug, or updating behavior
Reviewing your own diff before submitting — checking for scope creep in your changes
Working in a legacy codebase where preserving existing patterns is critical
Making hotfixes or patches where minimal change surface reduces risk
Contributing to a project with established coding conventions different from your preferences
Pair programming or code review where the reviewer values minimal diffs
When NOT to Use
Avoid this skill for:
Greenfield development or creating new files — use karpathy-coding-mindset instead
Large-scale refactoring initiatives where sweeping changes are intentional
Security fixes where defensive changes to adjacent code are justified
Performance optimization where changes to data structures affect multiple callers
Projects in early development where conventions are still being established
Core Workflow
Read Before You Write — Open the file(s) you need to modify. Read the entire file top to bottom. Understand the module's imports, function signatures, naming conventions, error handling patterns, and data flow. Checkpoint: Before writing any code, you should be able to describe the file's structure and conventions from memory.
Define the Minimal Change Set — List every file and function you plan to touch. For each change, state in one sentence how it traces to the user's request. If a change cannot be directly traced, remove it from the plan. Checkpoint: The union of all planned changes should exactly equal the user's request — no more, no less.
Match Existing Conventions — Identify the codebase's existing patterns for: naming (snake_case vs camelCase), imports (absolute vs relative), error handling (exceptions vs returns), formatting (line length, indentation), and testing style. Apply these conventions in your changes — even if you prefer a different style. Checkpoint: Your diff should be indistinguishable from code written by the project's existing authors.
Make the Surgical Edit — Implement exactly the changes from your plan. Do not reformat adjacent lines, do not update comments unless they refer to your changed code, do not add blank lines or remove them unless it's part of your change. Checkpoint: Run git diff and verify each changed line traces to the request.
Clean Up Your Orphans — Scan for imports, variables, or functions that YOUR edits made unused. Remove them. Do NOT touch pre-existing dead code — if you find any, leave a comment like # TODO: unused — pre-existing, not part of this change rather than deleting it. Checkpoint: The only deletions in your diff should be orphans created by your additions.
Verify No Scope Creep — Re-read the diff one final time. Classify every change as: (a) required by the request, (b) orphan cleanup from your changes, or (c) anything else. If category (c) is non-empty, revert those changes immediately. Checkpoint: Category (c) must be empty.
Implementation Patterns
Pattern 1: Surgical vs. Sweeping Change
# ❌ BAD — sweeping change: reformats, renames, refactors adjacent code
# Before: original file
def calc(a, b):
# Old calculation
res = a + b
return res
# After: "improved" version — renamed, reformatted, adjacent code changed
def calculate_total(value_one: float, value_two: float) -> float:
"""Calculate the total of two values.
This function was renamed from calc to be more descriptive.
Parameters were renamed from a,b to value_one,value_two.
Added type hints. Reformatted docstring. Changed return style.
None of these changes were requested.
"""
result_value = value_one + value_two
return result_value
# ✅ GOOD — surgical change: only what was requested
# Before: original file
def calc(a, b):
res = a + b
return res
# Request: handle negative numbers by returning 0
def calc(a, b):
res = a + b
# Handle negative results per request
if res < 0:
return 0
return res
# Changed lines: 3 lines added. Everything else preserved.
Pattern 2: Orphan Cleanup — Yours vs. Pre-existing
# ❌ BAD — deletes pre-existing dead code, misses own orphans
# Before: when adding a new function, you deleted unrelated dead code
import os # ← your code doesn't use os anymore, but it was unused before your change
import json # ← your code doesn't use json, pre-existing but should stay
from utils import old_helper, new_helper # old_helper was pre-existing dead code — you deleted it
def process(data):
# Your new implementation using new_helper
result = new_helper(data)
return result
# You forgot to remove the import of old_helper that YOUR change made unnecessary
# ✅ GOOD — removes own orphans, leaves pre-existing alone
import os # pre-existing, not touched
import json # pre-existing, not touched
from utils import old_helper, new_helper # old_helper was needed before, not touched
def process(data):
# Your new implementation using new_helper
result = new_helper(data)
return result
# Note: old_helper is still imported and that's fine — it was used elsewhere before
Pattern 3: Convention Matching
# ❌ BAD — imposing your style on an existing codebase
# Project convention: 2-space indentation, no type hints, exceptions for errors
# What you wrote:
def fetch_user(user_id: int) -> User | None:
"""Fetch user by ID from the database.
Args:
user_id: The user's unique identifier
Returns:
User object if found, None otherwise
"""
try:
return database.query(User).filter_by(id=user_id).first()
except DatabaseError:
return None
# ✅ GOOD — matches existing conventions
# Project convention: 2-space indentation, no type hints, exceptions for errors
# What you wrote (matching project style):
def fetch_user(user_id):
"""Fetch user by ID, raises on DB error, returns None if not found."""
return database.query(User).filter_by(id=user_id).first()
Pattern 4: Resist the Urge to "Improve"
# ❌ BAD — "improving" adjacent code while making requested change
# Request: "Add validation that email is not empty"
def create_user(name, email):
# You noticed the variable name is vague so you "improved" it
# You also reformatted the docstring
# You also added type hints (not in project style)
# You also fixed a typo in a comment on line 3
# None of these were requested
# Create new user with provided name and emial ← typo existed, you didn't touch it
user = User(name=name, email=email) # ← you changed 'name' to 'user_name' here
user.save()
return user
# ✅ GOOD — only the requested change, nothing else
# Request: "Add validation that email is not empty"
def create_user(name, email):
# Create new user with provided name and emial ← pre-existing typo, not touched
if not email: # ← only addition, per request
raise ValueError("Email is required")
user = User(name=name, email=email)
user.save()
return user
Constraints
MUST DO
Read the entire file you're editing before making any changes — understand context first
Match the codebase's existing naming, formatting, and error-handling conventions
Clean up imports, variables, and functions that YOUR changes made unused
Verify every changed line traces directly to the user's request using git diff
Mention pre-existing dead code in a comment if you discover it — do not delete it
MUST NOT DO
Refactor, rename, reformat, or "improve" adjacent code that isn't part of the request
Delete pre-existing dead code unless specifically asked to do so
Add type hints, docstrings, or error handling that don't match the project's existing patterns
Change indentation, line spacing, or comment style in unrelated sections
Fix typos or style issues in code you weren't asked to touch
Related Skills
Skill
Purpose
karpathy-coding-mindset
Pre-implementation discipline for new code — state assumptions, keep it simple
karpathy-goal-driven-execution
Post-implementation verification — define success criteria and verify
code-review
Reviewing diffs for quality and correctness
refactoring-techniques
When intentional, large-scale refactoring is the goal (not this skill)
1---2name: karpathy-surgical-changes3description: Enforces surgical code modification discipline — touch only what the request requires, read full context before editing, match existing codebase conventions, clean up only your own orphans, and never refactor adjacent code that isn't broken.4license: MIT5---67891011# Karpathy Surgical Changes1213Senior engineer applying surgical modification discipline: read the full context before editing, change only what the request demands, match existing codebase conventions even when you disagree, clean up only the orphans your changes create, and never refactor adjacent code that is not broken.1415Derived from [Andrej Karpathy's observations](https://x.com/karpathy/status/2015883857489522876) on LLM coding pitfalls — specifically the tendency to make sweeping changes when minimal edits are requested.1617---1819## TL;DR Checklist2021- [ ] Read the full file before making any edit — understand imports, dependencies, patterns22- [ ] Ask: "Does this change trace directly to the user's request?" If not, revert it23- [ ] Match existing code style, naming conventions, and patterns — even if you'd do it differently24- [ ] Remove imports, variables, and functions that YOUR changes made unused — but not pre-existing dead code25- [ ] Do NOT "improve" adjacent code, comments, formatting, or structure unless specifically asked26- [ ] If you notice unrelated dead code, mention it in a comment — do not delete it27- [ ] Every changed line must be necessary for the requested feature or fix2829---3031## When to Use3233Use this skill when:3435- Modifying existing code — adding a feature, fixing a bug, or updating behavior36- Reviewing your own diff before submitting — checking for scope creep in your changes37- Working in a legacy codebase where preserving existing patterns is critical38- Making hotfixes or patches where minimal change surface reduces risk39- Contributing to a project with established coding conventions different from your preferences40- Pair programming or code review where the reviewer values minimal diffs4142---4344## When NOT to Use4546Avoid this skill for:4748- Greenfield development or creating new files — use `karpathy-coding-mindset` instead49- Large-scale refactoring initiatives where sweeping changes are intentional50- Security fixes where defensive changes to adjacent code are justified51- Performance optimization where changes to data structures affect multiple callers52- Projects in early development where conventions are still being established5354---5556## Core Workflow57581. **Read Before You Write** — Open the file(s) you need to modify. Read the entire file top to bottom. Understand the module's imports, function signatures, naming conventions, error handling patterns, and data flow. **Checkpoint:** Before writing any code, you should be able to describe the file's structure and conventions from memory.59602. **Define the Minimal Change Set** — List every file and function you plan to touch. For each change, state in one sentence how it traces to the user's request. If a change cannot be directly traced, remove it from the plan. **Checkpoint:** The union of all planned changes should exactly equal the user's request — no more, no less.61623. **Match Existing Conventions** — Identify the codebase's existing patterns for: naming (snake_case vs camelCase), imports (absolute vs relative), error handling (exceptions vs returns), formatting (line length, indentation), and testing style. Apply these conventions in your changes — even if you prefer a different style. **Checkpoint:** Your diff should be indistinguishable from code written by the project's existing authors.63644. **Make the Surgical Edit** — Implement exactly the changes from your plan. Do not reformat adjacent lines, do not update comments unless they refer to your changed code, do not add blank lines or remove them unless it's part of your change. **Checkpoint:** Run `git diff` and verify each changed line traces to the request.65665. **Clean Up Your Orphans** — Scan for imports, variables, or functions that YOUR edits made unused. Remove them. Do NOT touch pre-existing dead code — if you find any, leave a comment like `# TODO: unused — pre-existing, not part of this change` rather than deleting it. **Checkpoint:** The only deletions in your diff should be orphans created by your additions.67686. **Verify No Scope Creep** — Re-read the diff one final time. Classify every change as: (a) required by the request, (b) orphan cleanup from your changes, or (c) anything else. If category (c) is non-empty, revert those changes immediately. **Checkpoint:** Category (c) must be empty.6970---7172## Implementation Patterns7374### Pattern 1: Surgical vs. Sweeping Change7576```python77# ❌ BAD — sweeping change: reformats, renames, refactors adjacent code7879# Before: original file80def calc(a, b):81 # Old calculation82 res = a + b83 return res8485# After: "improved" version — renamed, reformatted, adjacent code changed86def calculate_total(value_one: float, value_two: float) -> float:87 """Calculate the total of two values.8889 This function was renamed from calc to be more descriptive.90 Parameters were renamed from a,b to value_one,value_two.91 Added type hints. Reformatted docstring. Changed return style.92 None of these changes were requested.93 """94 result_value = value_one + value_two9596 return result_value9798# ✅ GOOD — surgical change: only what was requested99100# Before: original file101def calc(a, b):102 res = a + b103 return res104105# Request: handle negative numbers by returning 0106def calc(a, b):107 res = a + b108 # Handle negative results per request109 if res < 0:110 return 0111 return res112# Changed lines: 3 lines added. Everything else preserved.113```114115### Pattern 2: Orphan Cleanup — Yours vs. Pre-existing116117```python118# ❌ BAD — deletes pre-existing dead code, misses own orphans119120# Before: when adding a new function, you deleted unrelated dead code121import os # ← your code doesn't use os anymore, but it was unused before your change122import json # ← your code doesn't use json, pre-existing but should stay123from utils import old_helper, new_helper # old_helper was pre-existing dead code — you deleted it124125def process(data):126 # Your new implementation using new_helper127 result = new_helper(data)128 return result129 # You forgot to remove the import of old_helper that YOUR change made unnecessary130131# ✅ GOOD — removes own orphans, leaves pre-existing alone132133import os # pre-existing, not touched134import json # pre-existing, not touched135from utils import old_helper, new_helper # old_helper was needed before, not touched136137def process(data):138 # Your new implementation using new_helper139 result = new_helper(data)140 return result141# Note: old_helper is still imported and that's fine — it was used elsewhere before142```143144### Pattern 3: Convention Matching145146```python147# ❌ BAD — imposing your style on an existing codebase148149# Project convention: 2-space indentation, no type hints, exceptions for errors150# What you wrote:151def fetch_user(user_id: int) -> User | None:152 """Fetch user by ID from the database.153154 Args:155 user_id: The user's unique identifier156157 Returns:158 User object if found, None otherwise159 """160 try:161 return database.query(User).filter_by(id=user_id).first()162 except DatabaseError:163 return None164165# ✅ GOOD — matches existing conventions166167# Project convention: 2-space indentation, no type hints, exceptions for errors168# What you wrote (matching project style):169def fetch_user(user_id):170 """Fetch user by ID, raises on DB error, returns None if not found."""171 return database.query(User).filter_by(id=user_id).first()172```173174### Pattern 4: Resist the Urge to "Improve"175176```python177# ❌ BAD — "improving" adjacent code while making requested change178179# Request: "Add validation that email is not empty"180def create_user(name, email):181 # You noticed the variable name is vague so you "improved" it182 # You also reformatted the docstring183 # You also added type hints (not in project style)184 # You also fixed a typo in a comment on line 3185 # None of these were requested186187 # Create new user with provided name and emial ← typo existed, you didn't touch it188 user = User(name=name, email=email) # ← you changed 'name' to 'user_name' here189 user.save()190 return user191192# ✅ GOOD — only the requested change, nothing else193194# Request: "Add validation that email is not empty"195def create_user(name, email):196 # Create new user with provided name and emial ← pre-existing typo, not touched197 if not email: # ← only addition, per request198 raise ValueError("Email is required")199 user = User(name=name, email=email)200 user.save()201 return user202```203204---205206## Constraints207208### MUST DO209- Read the entire file you're editing before making any changes — understand context first210- Match the codebase's existing naming, formatting, and error-handling conventions211- Clean up imports, variables, and functions that YOUR changes made unused212- Verify every changed line traces directly to the user's request using `git diff`213- Mention pre-existing dead code in a comment if you discover it — do not delete it214215### MUST NOT DO216- Refactor, rename, reformat, or "improve" adjacent code that isn't part of the request217- Delete pre-existing dead code unless specifically asked to do so218- Add type hints, docstrings, or error handling that don't match the project's existing patterns219- Change indentation, line spacing, or comment style in unrelated sections220- Fix typos or style issues in code you weren't asked to touch221222---223224## Related Skills225226| Skill | Purpose |227|---|---|228| `karpathy-coding-mindset` | Pre-implementation discipline for new code — state assumptions, keep it simple |229| `karpathy-goal-driven-execution` | Post-implementation verification — define success criteria and verify |230| `code-review` | Reviewing diffs for quality and correctness |231| `refactoring-techniques` | When intentional, large-scale refactoring is the goal (not this skill) |
Run npx skillmds@latest add paulpas/karpathy-surgical-changes in your terminal (requires Node.js), paste this page's agent-chat prompt into Claude, Cursor, or any MCP-connected agent, or download the SKILL.md file and copy it into your agent's skills directory.
Enforces surgical code modification discipline — touch only what the request requires, read full context before editing, match existing codebase conventions, clean up only your own orphans, and never refactor adjacent code that isn't broken. It is listed under Coding & Dev Tools on SkillMD.
SkillMD's automated safety review verdict for this skill is PASS. Independent scanners report: SkillSpector: PASS, Skill Scanner: PASS. SkillMD never runs a skill's scripts for you; review the SKILL.md before installing.
This skill is tagged as working with Claude Code, Claude.ai, OpenAI Codex. SKILL.md is an open format, so most agents that read a skills directory can load it too.
Yes. Installing skills from SkillMD is free. This skill is licensed under MIT.
paulpas (@paulpas) published this skill. Their other Agent Skills are listed on their SkillMD profile.