| name | best-practices |
| description | Use for any code change — bug fix, small feature, refactor, or improvement. Ensures TDD, clarifying questions, codebase investigation, DRY, proper branching/worktrees, UI skills, and doc updates. PDD invokes this automatically for large features. |
Best-Practices-Driven Development (BPDD)
Overview
The baseline discipline for every code change, no matter how small — a bug fix, a refactor, a small feature. plan-driven-development invokes this automatically for large multi-milestone features; use it directly for smaller work.
Before any of this: if the change is a new user-facing feature, run powerups:user-research first — it produces the discovery brief (problem statement, jobs-to-be-done, core flow, decision matrix) that confirms you're building the right thing. That skill owns the skip conditions. plan-driven-development and give-me-five already invoke it at the right moment; this pointer is for standalone feature work.
The Practices
1. Never Develop on Main
Create a branch before writing any code: git checkout -b feature/name. Never commit directly to main.
2. Investigate Before Building (DRY)
Before writing code, spawn an Explore subagent to find what already exists:
"Investigate the codebase for [feature/problem]. Check: (1) does similar code already exist, (2) do existing services or third-party deps already handle this, (3) what patterns are used for similar features. Return a concise summary under 30 lines."
All investigation happens in subagents to protect main context — they return summaries, not raw file contents.
- If similar code exists: extend or generalize it. Never create a second version of the same thing.
- If you find duplication after writing code: refactor immediately, don't leave it for later.
- Three similar lines of code beat a premature abstraction — but three similar functions should be consolidated.
- Registry patterns (a dict mapping keys to functions/configs) beat if/else chains for similar operations with different configurations.
Third-party APIs and libraries: WebSearch the latest official docs before writing integration code — verify parameter names, required fields, response shapes, and recent breaking changes. Do not rely on training knowledge alone; APIs deprecate endpoints and rename parameters.
3. Impact Scan Before Changing Existing Code
Before modifying an existing function, API, database schema, or shared utility, scan everything that depends on it. Scale to the blast radius: one scan for a small local change, all 3 in parallel for signature, schema, shared-utility, or API-shape changes.
Run scans as general-purpose subagents with this prompt shape:
"I'm modifying [function/module/table]. Find EVERY [scan target] across the entire codebase. For each: file path, line number, exact usage, whether it needs updating."
- Scan 1 — Callers: every import (including aliased), every direct and indirect call site, hardcoded values matching defaults being changed, sibling functions, and cron / background tasks / webhooks that trigger this code path — the scan always finds surprising callers.
- Scan 2 — Data: every query on the affected tables, every column reference, every ORM/Pydantic model mapping to the table, every RPC touching this data, every place constructing rows or dicts matching the schema.
- Scan 3 — Tests: every test file importing or calling the changed code, fixtures setting up this path, assertions depending on current behavior, mocks/patches targeting it, end-to-end tests exercising it.
Merge findings into a single impact picture. If using PDD, add a "Callers Impacted" section to the plan; otherwise verify each caller is handled before marking the work done. Update any caller that passes explicit values matching old defaults you're changing.
This differs from practice #2: #2 asks "does similar code exist?" to avoid reinventing. This asks "what breaks when I change this?" to avoid incomplete changes.
4. Ask Before You Assume
Use AskUserQuestion to clarify before building. Don't guess at requirements, scope, or approach:
- What they actually want — don't infer, confirm. And who the user is: developer, their customer, or end-user?
- Scope — specific to one case, or generic for future use?
- Backwards compatibility — keep the old code or delete it? (Most of the time: delete it)
- Tradeoffs — present the better option even if it's harder. Don't default to easy.
If the request is ambiguous, ask — don't pick an interpretation. If you're about to make a product decision, surface it. Batch related questions into one message.
5. Test-Driven Development
Invoke powerups:test-driven-development. Failing test first, minimal code to pass, refactor. No mocks — tests hit real infrastructure. That skill owns the details.
6. No Backward Compatibility by Default
Do NOT implement backward compatibility or legacy methods unless explicitly asked.
- When making breaking changes, ask: "Do you need backward compatibility for this change?" Most of the time the answer is no — just update all usages directly.
- Avoid: renamed variables with old aliases, deprecated function wrappers, legacy API endpoints, re-exports for old import paths.
- If old code is unused after the change, delete it completely — no
# removed comments, no _unused variables.
7. UI Work: Design Skills
If the change touches anything the user sees, invoke both:
simple-design-principles — copy and labels, toasts, empty states, error messages, component selection
frontend-design — visual design for new or modified components, pages, loading/error states
8. Self-Documenting APIs
If the change adds or modifies API endpoints, invoke self-documenting-apis — endpoint docstrings, typed request/response models with field descriptions, status codes, router tags. Auto-generated docs (/docs, /redoc) are the only API reference; never maintain a separate api-reference.md.
9. Finish: Simplify → Change Log → Docs → Lint → Tests
The canonical completion sequence for any code change — plan-driven-development and bug-fix reference this instead of restating it. Run after the code works, in this order:
/simplify — review changed code for reuse, quality, and efficiency (duplicate code, N+1 queries, anti-patterns). Fix what it finds.
powerups:change-log — CHANGELOG.md entry in plain language. User-facing changes only.
update-docs — sync CLAUDE.md, README, guides, sibling repos. Small changes cause drift too.
- Lint — run the project's linter (
ruff check, npm run lint, …). Fix issues in files you changed; leave pre-existing issues in untouched files.
- Full test suite — all tests pass, not just the ones you added.
Quick Reference
0. User-research (new user-facing features)
1. Branch (never main)
2. Investigate + DRY (Explore subagent; WebSearch 3rd-party docs)
3. Impact scan (what breaks?)
4. Ask (clarify requirements with user)
5. TDD (invoke the skill)
6. No backward compat (unless explicitly asked)
7. UI → simple-design-principles + frontend-design
8. API → self-documenting-apis
9. Finish: simplify → change-log → update-docs → lint → full suite