Guide for continuous improvement, error proofing, and standardization. Use this skill when the user wants to improve code quality, refactor, or discuss process improvements.
npx mdskills install sickn33/kaizen@sickn33? Sign in with GitHub to claim this listing.Comprehensive philosophy guide with clear TypeScript examples demonstrating iterative improvement patterns
1---2name: kaizen3description: Guide for continuous improvement, error proofing, and standardization. Use this skill when the user wants to improve code quality, refactor, or discuss process improvements.4---56# Kaizen: Continuous Improvement78## Overview910Small improvements, continuously. Error-proof by design. Follow what works. Build only what's needed.1112**Core principle:** Many small improvements beat one big change. Prevent errors at design time, not with fixes.1314## When to Use1516**Always applied for:**1718- Code implementation and refactoring19- Architecture and design decisions20- Process and workflow improvements21- Error handling and validation2223**Philosophy:** Quality through incremental progress and prevention, not perfection through massive effort.2425## The Four Pillars2627### 1. Continuous Improvement (Kaizen)2829Small, frequent improvements compound into major gains.3031#### Principles3233**Incremental over revolutionary:**3435- Make smallest viable change that improves quality36- One improvement at a time37- Verify each change before next38- Build momentum through small wins3940**Always leave code better:**4142- Fix small issues as you encounter them43- Refactor while you work (within scope)44- Update outdated comments45- Remove dead code when you see it4647**Iterative refinement:**4849- First version: make it work50- Second pass: make it clear51- Third pass: make it efficient52- Don't try all three at once5354<Good>55```typescript56// Iteration 1: Make it work57const calculateTotal = (items: Item[]) => {58 let total = 0;59 for (let i = 0; i < items.length; i++) {60 total += items[i].price * items[i].quantity;61 }62 return total;63};6465// Iteration 2: Make it clear (refactor)66const calculateTotal = (items: Item[]): number => {67return items.reduce((total, item) => {68return total + (item.price \* item.quantity);69}, 0);70};7172// Iteration 3: Make it robust (add validation)73const calculateTotal = (items: Item[]): number => {74if (!items?.length) return 0;7576return items.reduce((total, item) => {77if (item.price < 0 || item.quantity < 0) {78throw new Error('Price and quantity must be non-negative');79}80return total + (item.price \* item.quantity);81}, 0);82};8384````85Each step is complete, tested, and working86</Good>8788<Bad>89```typescript90// Trying to do everything at once91const calculateTotal = (items: Item[]): number => {92 // Validate, optimize, add features, handle edge cases all together93 if (!items?.length) return 0;94 const validItems = items.filter(item => {95 if (item.price < 0) throw new Error('Negative price');96 if (item.quantity < 0) throw new Error('Negative quantity');97 return item.quantity > 0; // Also filtering zero quantities98 });99 // Plus caching, plus logging, plus currency conversion...100 return validItems.reduce(...); // Too many concerns at once101};102````103104Overwhelming, error-prone, hard to verify105</Bad>106107#### In Practice108109**When implementing features:**1101111. Start with simplest version that works1122. Add one improvement (error handling, validation, etc.)1133. Test and verify1144. Repeat if time permits1155. Don't try to make it perfect immediately116117**When refactoring:**118119- Fix one smell at a time120- Commit after each improvement121- Keep tests passing throughout122- Stop when "good enough" (diminishing returns)123124**When reviewing code:**125126- Suggest incremental improvements (not rewrites)127- Prioritize: critical → important → nice-to-have128- Focus on highest-impact changes first129- Accept "better than before" even if not perfect130131### 2. Poka-Yoke (Error Proofing)132133Design systems that prevent errors at compile/design time, not runtime.134135#### Principles136137**Make errors impossible:**138139- Type system catches mistakes140- Compiler enforces contracts141- Invalid states unrepresentable142- Errors caught early (left of production)143144**Design for safety:**145146- Fail fast and loudly147- Provide helpful error messages148- Make correct path obvious149- Make incorrect path difficult150151**Defense in layers:**1521531. Type system (compile time)1542. Validation (runtime, early)1553. Guards (preconditions)1564. Error boundaries (graceful degradation)157158#### Type System Error Proofing159160<Good>161```typescript162// Error: string status can be any value163type OrderBad = {164 status: string; // Can be "pending", "PENDING", "pnding", anything!165 total: number;166};167168// Good: Only valid states possible169type OrderStatus = 'pending' | 'processing' | 'shipped' | 'delivered';170type Order = {171status: OrderStatus;172total: number;173};174175// Better: States with associated data176type Order =177| { status: 'pending'; createdAt: Date }178| { status: 'processing'; startedAt: Date; estimatedCompletion: Date }179| { status: 'shipped'; trackingNumber: string; shippedAt: Date }180| { status: 'delivered'; deliveredAt: Date; signature: string };181182// Now impossible to have shipped without trackingNumber183184````185Type system prevents entire classes of errors186</Good>187188<Good>189```typescript190// Make invalid states unrepresentable191type NonEmptyArray<T> = [T, ...T[]];192193const firstItem = <T>(items: NonEmptyArray<T>): T => {194 return items[0]; // Always safe, never undefined!195};196197// Caller must prove array is non-empty198const items: number[] = [1, 2, 3];199if (items.length > 0) {200 firstItem(items as NonEmptyArray<number>); // Safe201}202````203204Function signature guarantees safety205</Good>206207#### Validation Error Proofing208209<Good>210```typescript211// Error: Validation after use212const processPayment = (amount: number) => {213 const fee = amount * 0.03; // Used before validation!214 if (amount <= 0) throw new Error('Invalid amount');215 // ...216};217218// Good: Validate immediately219const processPayment = (amount: number) => {220if (amount <= 0) {221throw new Error('Payment amount must be positive');222}223if (amount > 10000) {224throw new Error('Payment exceeds maximum allowed');225}226227const fee = amount \* 0.03;228// ... now safe to use229};230231// Better: Validation at boundary with branded type232type PositiveNumber = number & { readonly \_\_brand: 'PositiveNumber' };233234const validatePositive = (n: number): PositiveNumber => {235if (n <= 0) throw new Error('Must be positive');236return n as PositiveNumber;237};238239const processPayment = (amount: PositiveNumber) => {240// amount is guaranteed positive, no need to check241const fee = amount \* 0.03;242};243244// Validate at system boundary245const handlePaymentRequest = (req: Request) => {246const amount = validatePositive(req.body.amount); // Validate once247processPayment(amount); // Use everywhere safely248};249250````251Validate once at boundary, safe everywhere else252</Good>253254#### Guards and Preconditions255256<Good>257```typescript258// Early returns prevent deeply nested code259const processUser = (user: User | null) => {260 if (!user) {261 logger.error('User not found');262 return;263 }264265 if (!user.email) {266 logger.error('User email missing');267 return;268 }269270 if (!user.isActive) {271 logger.info('User inactive, skipping');272 return;273 }274275 // Main logic here, guaranteed user is valid and active276 sendEmail(user.email, 'Welcome!');277};278````279280Guards make assumptions explicit and enforced281</Good>282283#### Configuration Error Proofing284285<Good>286```typescript287// Error: Optional config with unsafe defaults288type ConfigBad = {289 apiKey?: string;290 timeout?: number;291};292293const client = new APIClient({ timeout: 5000 }); // apiKey missing!294295// Good: Required config, fails early296type Config = {297apiKey: string;298timeout: number;299};300301const loadConfig = (): Config => {302const apiKey = process.env.API_KEY;303if (!apiKey) {304throw new Error('API_KEY environment variable required');305}306307return {308apiKey,309timeout: 5000,310};311};312313// App fails at startup if config invalid, not during request314const config = loadConfig();315const client = new APIClient(config);316317````318Fail at startup, not in production319</Good>320321#### In Practice322323**When designing APIs:**324- Use types to constrain inputs325- Make invalid states unrepresentable326- Return Result<T, E> instead of throwing327- Document preconditions in types328329**When handling errors:**330- Validate at system boundaries331332- Use guards for preconditions333- Fail fast with clear messages334- Log context for debugging335336**When configuring:**337- Required over optional with defaults338- Validate all config at startup339- Fail deployment if config invalid340- Don't allow partial configurations341342### 3. Standardized Work343Follow established patterns. Document what works. Make good practices easy to follow.344345#### Principles346347**Consistency over cleverness:**348- Follow existing codebase patterns349- Don't reinvent solved problems350- New pattern only if significantly better351- Team agreement on new patterns352353**Documentation lives with code:**354- README for setup and architecture355- CLAUDE.md for AI coding conventions356- Comments for "why", not "what"357- Examples for complex patterns358359**Automate standards:**360- Linters enforce style361- Type checks enforce contracts362- Tests verify behavior363- CI/CD enforces quality gates364365#### Following Patterns366367<Good>368```typescript369// Existing codebase pattern for API clients370class UserAPIClient {371 async getUser(id: string): Promise<User> {372 return this.fetch(`/users/${id}`);373 }374}375376// New code follows the same pattern377class OrderAPIClient {378 async getOrder(id: string): Promise<Order> {379 return this.fetch(`/orders/${id}`);380 }381}382````383384Consistency makes codebase predictable385</Good>386387<Bad>388```typescript389// Existing pattern uses classes390class UserAPIClient { /* ... */ }391392// New code introduces different pattern without discussion393const getOrder = async (id: string): Promise<Order> => {394// Breaking consistency "because I prefer functions"395};396397````398Inconsistency creates confusion399</Bad>400401#### Error Handling Patterns402403<Good>404```typescript405// Project standard: Result type for recoverable errors406type Result<T, E> = { ok: true; value: T } | { ok: false; error: E };407408// All services follow this pattern409const fetchUser = async (id: string): Promise<Result<User, Error>> => {410 try {411 const user = await db.users.findById(id);412 if (!user) {413 return { ok: false, error: new Error('User not found') };414 }415 return { ok: true, value: user };416 } catch (err) {417 return { ok: false, error: err as Error };418 }419};420421// Callers use consistent pattern422const result = await fetchUser('123');423if (!result.ok) {424 logger.error('Failed to fetch user', result.error);425 return;426}427const user = result.value; // Type-safe!428````429430Standard pattern across codebase431</Good>432433#### Documentation Standards434435<Good>436```typescript437/**438 * Retries an async operation with exponential backoff.439 *440 * Why: Network requests fail temporarily; retrying improves reliability441 * When to use: External API calls, database operations442 * When not to use: User input validation, internal function calls443 *444 * @example445 * const result = await retry(446 * () => fetch('https://api.example.com/data'),447 * { maxAttempts: 3, baseDelay: 1000 }448 * );449 */450const retry = async <T>(451 operation: () => Promise<T>,452 options: RetryOptions453): Promise<T> => {454 // Implementation...455};456```457Documents why, when, and how458</Good>459460#### In Practice461462**Before adding new patterns:**463464- Search codebase for similar problems solved465- Check CLAUDE.md for project conventions466- Discuss with team if breaking from pattern467- Update docs when introducing new pattern468469**When writing code:**470471- Match existing file structure472- Use same naming conventions473- Follow same error handling approach474- Import from same locations475476**When reviewing:**477478- Check consistency with existing code479- Point to examples in codebase480- Suggest aligning with standards481- Update CLAUDE.md if new standard emerges482483### 4. Just-In-Time (JIT)484485Build what's needed now. No more, no less. Avoid premature optimization and over-engineering.486487#### Principles488489**YAGNI (You Aren't Gonna Need It):**490491- Implement only current requirements492- No "just in case" features493- No "we might need this later" code494- Delete speculation495496**Simplest thing that works:**497498- Start with straightforward solution499- Add complexity only when needed500- Refactor when requirements change501- Don't anticipate future needs502503**Optimize when measured:**504505- No premature optimization506- Profile before optimizing507- Measure impact of changes508- Accept "good enough" performance509510#### YAGNI in Action511512<Good>513```typescript514// Current requirement: Log errors to console515const logError = (error: Error) => {516 console.error(error.message);517};518```519Simple, meets current need520</Good>521522<Bad>523```typescript524// Over-engineered for "future needs"525interface LogTransport {526 write(level: LogLevel, message: string, meta?: LogMetadata): Promise<void>;527}528529class ConsoleTransport implements LogTransport { /_... _/ }530class FileTransport implements LogTransport { /_ ... _/ }531class RemoteTransport implements LogTransport { /_ ..._/ }532533class Logger {534private transports: LogTransport[] = [];535private queue: LogEntry[] = [];536private rateLimiter: RateLimiter;537private formatter: LogFormatter;538539// 200 lines of code for "maybe we'll need it"540}541542const logError = (error: Error) => {543Logger.getInstance().log('error', error.message);544};545546````547Building for imaginary future requirements548</Bad>549550**When to add complexity:**551- Current requirement demands it552- Pain points identified through use553- Measured performance issues554- Multiple use cases emerged555556<Good>557```typescript558// Start simple559const formatCurrency = (amount: number): string => {560 return `$${amount.toFixed(2)}`;561};562563// Requirement evolves: support multiple currencies564const formatCurrency = (amount: number, currency: string): string => {565 const symbols = { USD: '$', EUR: '€', GBP: '£' };566 return `${symbols[currency]}${amount.toFixed(2)}`;567};568569// Requirement evolves: support localization570const formatCurrency = (amount: number, locale: string): string => {571 return new Intl.NumberFormat(locale, {\n style: 'currency',572 currency: locale === 'en-US' ? 'USD' : 'EUR',573 }).format(amount);574};575````576577Complexity added only when needed578</Good>579580#### Premature Abstraction581582<Bad>583```typescript584// One use case, but building generic framework585abstract class BaseCRUDService<T> {586 abstract getAll(): Promise<T[]>;587 abstract getById(id: string): Promise<T>;588 abstract create(data: Partial<T>): Promise<T>;589 abstract update(id: string, data: Partial<T>): Promise<T>;590 abstract delete(id: string): Promise<void>;591}592593class GenericRepository<T> { /_300 lines _/ }594class QueryBuilder<T> { /_ 200 lines_/ }595// ... building entire ORM for single table596597````598Massive abstraction for uncertain future599</Bad>600601<Good>602```typescript603// Simple functions for current needs604const getUsers = async (): Promise<User[]> => {605 return db.query('SELECT * FROM users');606};607608const getUserById = async (id: string): Promise<User | null> => {609 return db.query('SELECT * FROM users WHERE id = $1', [id]);610};611612// When pattern emerges across multiple entities, then abstract613````614615Abstract only when pattern proven across 3+ cases616</Good>617618#### Performance Optimization619620<Good>621```typescript622// Current: Simple approach623const filterActiveUsers = (users: User[]): User[] => {624 return users.filter(user => user.isActive);625};626627// Benchmark shows: 50ms for 1000 users (acceptable)628// ✓ Ship it, no optimization needed629630// Later: After profiling shows this is bottleneck631// Then optimize with indexed lookup or caching632633````634Optimize based on measurement, not assumptions635</Good>636637<Bad>638```typescript639// Premature optimization640const filterActiveUsers = (users: User[]): User[] => {641 // "This might be slow, so let's cache and index"642 const cache = new WeakMap();643 const indexed = buildBTreeIndex(users, 'isActive');644 // 100 lines of optimization code645 // Adds complexity, harder to maintain646 // No evidence it was needed647};\648````649650Complex solution for unmeasured problem651</Bad>652653#### In Practice654655**When implementing:**656657- Solve the immediate problem658- Use straightforward approach659- Resist "what if" thinking660- Delete speculative code661662**When optimizing:**663664- Profile first, optimize second665- Measure before and after666- Document why optimization needed667- Keep simple version in tests668669**When abstracting:**670671- Wait for 3+ similar cases (Rule of Three)672- Make abstraction as simple as possible673- Prefer duplication over wrong abstraction674- Refactor when pattern clear675676## Integration with Commands677678The Kaizen skill guides how you work. The commands provide structured analysis:679680- **`/why`**: Root cause analysis (5 Whys)681- **`/cause-and-effect`**: Multi-factor analysis (Fishbone)682- **`/plan-do-check-act`**: Iterative improvement cycles683- **`/analyse-problem`**: Comprehensive documentation (A3)684- **`/analyse`**: Smart method selection (Gemba/VSM/Muda)685686Use commands for structured problem-solving. Apply skill for day-to-day development.687688## Red Flags689690**Violating Continuous Improvement:**691692- "I'll refactor it later" (never happens)693- Leaving code worse than you found it694- Big bang rewrites instead of incremental695696**Violating Poka-Yoke:**697698- "Users should just be careful"699- Validation after use instead of before700- Optional config with no validation701702**Violating Standardized Work:**703704- "I prefer to do it my way"705- Not checking existing patterns706- Ignoring project conventions707708**Violating Just-In-Time:**709710- "We might need this someday"711- Building frameworks before using them712- Optimizing without measuring713714## Remember715716**Kaizen is about:**717718- Small improvements continuously719- Preventing errors by design720- Following proven patterns721- Building only what's needed722723**Not about:**724725- Perfection on first try726- Massive refactoring projects727- Clever abstractions728- Premature optimization729730**Mindset:** Good enough today, better tomorrow. Repeat.731
Full transparency — inspect the skill content before installing.