From solo-sdlc
Apply LLM coding discipline to every edit - minimum code, surgical changes, surface assumptions, goal-driven execution. Use this skill ALWAYS when writing or editing code, especially when modifying existing files. Triggers on any code-writing task, refactor, bug fix, or feature implementation. Inspired by Karpathy's observations on common LLM coding pitfalls. Prevents overcomplication, scope creep, silent assumptions, and weak success criteria.
How this skill is triggered — by the user, by Claude, or both
Slash command
/solo-sdlc:code-disciplineThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Karpathy's observation: "Models make wrong assumptions on your behalf and just run along with them without checking. They don't manage their confusion, don't seek clarifications, don't surface inconsistencies, don't present tradeoffs, don't push back when they should. They really like to overcomplicate code and APIs, bloat abstractions, implement a bloated construction over 1000 lines when 100 ...
Karpathy's observation: "Models make wrong assumptions on your behalf and just run along with them without checking. They don't manage their confusion, don't seek clarifications, don't surface inconsistencies, don't present tradeoffs, don't push back when they should. They really like to overcomplicate code and APIs, bloat abstractions, implement a bloated construction over 1000 lines when 100 would do."
This skill makes those failures impossible.
The goal is the smallest correct change.
Tests:
Examples:
❌ Bloated:
class UserService:
def __init__(self, repo: UserRepository, cache: Optional[CacheBackend] = None,
metrics: Optional[MetricsBackend] = None,
feature_flags: Optional[FeatureFlagBackend] = None):
self._repo = repo
self._cache = cache or NullCache()
self._metrics = metrics or NullMetrics()
self._flags = feature_flags or NullFlags()
async def get_user(self, user_id: str) -> User | None:
# ... 30 lines of cache check, metrics, flags ...
✅ Minimum:
async def get_user(repo: UserRepo, user_id: str) -> User | None:
return await repo.find_by_id(user_id)
If caching is needed later, add it then. Don't pre-build for a hypothetical future.
Touch only what you must.
Dead code rule:
The trace test: every changed line should trace directly to what was requested. If a line changed and you can't say WHY (mapping to the user's request), revert it.
Examples:
❌ Scope creep:
customerType to customerCategory AND adds doc comments AND reformats with new linter rules✅ Surgical:
customerType is a bad name, leave it. Even if there are no doc comments, don't add them. Mention "noticed customerType could be clearer; not changing per scope" in your output.When unsure - say so.
The fastest way to waste hours: assume something silently and code on top of it.
When this rule applies:
Surface assumption template:
"Before I implement: [request] - I'm reading this as X. Could also mean Y. Which?"
OR
"I'll need to [decision]. Two options:
- Option A: [pros/cons]
- Option B: [pros/cons] Going with A unless you say otherwise."
Anti-pattern (the failure mode):
User: "Add user search" You: silently decide to do prefix search, in-memory, case-sensitive, with pagination of 20, no permissions filter 30 minutes later: user has wrong implementation, has to ask for changes
Correct:
User: "Add user search" You: "Quick check before implementing:
- Search by what fields? (email + name? email only?)
- Substring or prefix?
- Case sensitive?
- Apply visibility/permission filter?
- Pagination size?
Defaults if you say 'just go': email+name, substring, case-insensitive, visibility-filtered, 20 per page."
Define success BEFORE starting. Loop until verified.
Karpathy: "LLMs are exceptionally good at looping until they meet specific goals. Don't tell it what to do, give it success criteria and watch it go."
The transformation:
getUserProfile p95 < 50ms when called repeatedly with same ID. Verify by running bench-getUserProfile.sh."Before starting any implementation:
If the user gave a weak goal: Push back: "Before I start - how will we know this is done? What's the test?"
Examples of weak vs strong:
❌ "Make it faster"
✅ "Cut p95 latency on /api/users from 800ms to <200ms, verified by running our load test for 5 minutes"
❌ "Make the UI nicer"
✅ "Match the mockup at docs/design/dashboard-v2.png, verify by side-by-side screenshot"
❌ "Refactor this"
✅ "Reduce CalculateShipping from 200 lines to <80 while keeping all current tests green; specifically split into 3 functions: validate, calculate, format"
For every code-writing task:
## Understanding
- Request: <one sentence>
- Interpretation: <yours>
- Assumptions: <list, especially uncertain ones>
## Success criteria
- <concrete, testable>
## Plan (minimum diff)
- File: <path> - <what changes>
- File: <path> - <what changes>
## Out of scope (noticed but not touching)
- <unrelated issue you saw>
## Verification
- Command: <how to verify>
- Result: <after running>
Before submitting any change, ask yourself:
Any "yes" to the first three or "no" to the last two = revise before output.
Provides 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.
npx claudepluginhub shakhovskiya-create/shakhoff-claude-marketplace --plugin solo-sdlc