kaizen:kaizen — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited kaizen:kaizen (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Apply continuous improvement mindset - suggest small iterative improvements, error-proof designs, follow established patterns, avoid over-engineering; automatically applied to guide quality and simplicity
Small improvements, continuously. Error-proof by design. Follow what works. Build only what's needed.
Core principle: Many small improvements beat one big change. Prevent errors at design time, not with fixes.
Always applied for:
Philosophy: Quality through incremental progress and prevention, not perfection through massive effort.
Small, frequent improvements compound into major gains.
#### Principles
Incremental over revolutionary:
Always leave code better:
Iterative refinement:
<Good>
// Iteration 1: Make it work
const calculateTotal = (items: Item[]) => {
let total = 0;
for (let i = 0; i < items.length; i++) {
total += items[i].price * items[i].quantity;
}
return total;
};
// Iteration 2: Make it clear (refactor)
const calculateTotal = (items: Item[]): number => {
return items.reduce((total, item) => {
return total + (item.price * item.quantity);
}, 0);
};
// Iteration 3: Make it robust (add validation)
const calculateTotal = (items: Item[]): number => {
if (!items?.length) return 0;
return items.reduce((total, item) => {
if (item.price < 0 || item.quantity < 0) {
throw new Error('Price and quantity must be non-negative');
}
return total + (item.price * item.quantity);
}, 0);
};
Each step is complete, tested, and working </Good>
<Bad>
// Trying to do everything at once
const calculateTotal = (items: Item[]): number => {
// Validate, optimize, add features, handle edge cases all together
if (!items?.length) return 0;
const validItems = items.filter(item => {
if (item.price < 0) throw new Error('Negative price');
if (item.quantity < 0) throw new Error('Negative quantity');
return item.quantity > 0; // Also filtering zero quantities
});
// Plus caching, plus logging, plus currency conversion...
return validItems.reduce(...); // Too many concerns at once
};Overwhelming, error-prone, hard to verify </Bad>
#### In Practice
When implementing features:
When refactoring:
When reviewing code:
Design systems that prevent errors at compile/design time, not runtime.
#### Principles
Make errors impossible:
Design for safety:
Defense in layers:
#### Type System Error Proofing
<Good>
// Error: string status can be any value
type OrderBad = {
status: string; // Can be "pending", "PENDING", "pnding", anything!
total: number;
};
// Good: Only valid states possible
type OrderStatus = 'pending' | 'processing' | 'shipped' | 'delivered';
type Order = {
status: OrderStatus;
total: number;
};
// Better: States with associated data
type Order =
| { status: 'pending'; createdAt: Date }
| { status: 'processing'; startedAt: Date; estimatedCompletion: Date }
| { status: 'shipped'; trackingNumber: string; shippedAt: Date }
| { status: 'delivered'; deliveredAt: Date; signature: string };
// Now impossible to have shipped without trackingNumber
Type system prevents entire classes of errors </Good>
<Good>
// Make invalid states unrepresentable
type NonEmptyArray<T> = [T, ...T[]];
const firstItem = <T>(items: NonEmptyArray<T>): T => {
return items[0]; // Always safe, never undefined!
};
// Caller must prove array is non-empty
const items: number[] = [1, 2, 3];
if (items.length > 0) {
firstItem(items as NonEmptyArray<number>); // Safe
}Function signature guarantees safety </Good>
#### Validation Error Proofing
<Good>
// Error: Validation after use
const processPayment = (amount: number) => {
const fee = amount * 0.03; // Used before validation!
if (amount <= 0) throw new Error('Invalid amount');
// ...
};
// Good: Validate immediately
const processPayment = (amount: number) => {
if (amount <= 0) {
throw new Error('Payment amount must be positive');
}
if (amount > 10000) {
throw new Error('Payment exceeds maximum allowed');
}
const fee = amount * 0.03;
// ... now safe to use
};
// Better: Validation at boundary with branded type
type PositiveNumber = number & { readonly __brand: 'PositiveNumber' };
const validatePositive = (n: number): PositiveNumber => {
if (n <= 0) throw new Error('Must be positive');
return n as PositiveNumber;
};
const processPayment = (amount: PositiveNumber) => {
// amount is guaranteed positive, no need to check
const fee = amount * 0.03;
};
// Validate at system boundary
const handlePaymentRequest = (req: Request) => {
const amount = validatePositive(req.body.amount); // Validate once
processPayment(amount); // Use everywhere safely
};
Validate once at boundary, safe everywhere else </Good>
#### Guards and Preconditions
<Good>
// Early returns prevent deeply nested code
const processUser = (user: User | null) => {
if (!user) {
logger.error('User not found');
return;
}
if (!user.email) {
logger.error('User email missing');
return;
}
if (!user.isActive) {
logger.info('User inactive, skipping');
return;
}
// Main logic here, guaranteed user is valid and active
sendEmail(user.email, 'Welcome!');
};Guards make assumptions explicit and enforced </Good>
#### Configuration Error Proofing
<Good>
// Error: Optional config with unsafe defaults
type ConfigBad = {
apiKey?: string;
timeout?: number;
};
const client = new APIClient({ timeout: 5000 }); // apiKey missing!
// Good: Required config, fails early
type Config = {
apiKey: string;
timeout: number;
};
const loadConfig = (): Config => {
const apiKey = process.env.API_KEY;
if (!apiKey) {
throw new Error('API_KEY environment variable required');
}
return {
apiKey,
timeout: 5000,
};
};
// App fails at startup if config invalid, not during request
const config = loadConfig();
const client = new APIClient(config);
Fail at startup, not in production </Good>
#### In Practice
When designing APIs:
When handling errors:
When configuring:
Follow established patterns. Document what works. Make good practices easy to follow.
#### Principles
Consistency over cleverness:
Documentation lives with code:
Automate standards:
#### Following Patterns
<Good>
// Existing codebase pattern for API clients
class UserAPIClient {
async getUser(id: string): Promise<User> {
return this.fetch(`/users/${id}`);
}
}
// New code follows the same pattern
class OrderAPIClient {
async getOrder(id: string): Promise<Order> {
return this.fetch(`/orders/${id}`);
}
}Consistency makes codebase predictable </Good>
<Bad>
// Existing pattern uses classes
class UserAPIClient { /* ... */ }
// New code introduces different pattern without discussion
const getOrder = async (id: string): Promise<Order> => {
// Breaking consistency "because I prefer functions"
};
Inconsistency creates confusion </Bad>
#### Error Handling Patterns
<Good>
// Project standard: Result type for recoverable errors
type Result<T, E> = { ok: true; value: T } | { ok: false; error: E };
// All services follow this pattern
const fetchUser = async (id: string): Promise<Result<User, Error>> => {
try {
const user = await db.users.findById(id);
if (!user) {
return { ok: false, error: new Error('User not found') };
}
return { ok: true, value: user };
} catch (err) {
return { ok: false, error: err as Error };
}
};
// Callers use consistent pattern
const result = await fetchUser('123');
if (!result.ok) {
logger.error('Failed to fetch user', result.error);
return;
}
const user = result.value; // Type-safe!Standard pattern across codebase </Good>
#### Documentation Standards
<Good>
/**
* Retries an async operation with exponential backoff.
*
* Why: Network requests fail temporarily; retrying improves reliability
* When to use: External API calls, database operations
* When not to use: User input validation, internal function calls
*
* @example
* const result = await retry(
* () => fetch('https://api.example.com/data'),
* { maxAttempts: 3, baseDelay: 1000 }
* );
*/
const retry = async <T>(
operation: () => Promise<T>,
options: RetryOptions
): Promise<T> => {
// Implementation...
};Documents why, when, and how </Good>
#### In Practice
Before adding new patterns:
When writing code:
When reviewing:
Build what's needed now. No more, no less. Avoid premature optimization and over-engineering.
#### Principles
YAGNI (You Aren't Gonna Need It):
Simplest thing that works:
Optimize when measured:
#### YAGNI in Action
<Good>
// Current requirement: Log errors to console
const logError = (error: Error) => {
console.error(error.message);
};Simple, meets current need </Good>
<Bad>
// Over-engineered for "future needs"
interface LogTransport {
write(level: LogLevel, message: string, meta?: LogMetadata): Promise<void>;
}
class ConsoleTransport implements LogTransport { /*... */ }
class FileTransport implements LogTransport { /* ... */ }
class RemoteTransport implements LogTransport { /* ...*/ }
class Logger {
private transports: LogTransport[] = [];
private queue: LogEntry[] = [];
private rateLimiter: RateLimiter;
private formatter: LogFormatter;
// 200 lines of code for "maybe we'll need it"
}
const logError = (error: Error) => {
Logger.getInstance().log('error', error.message);
};
Building for imaginary future requirements </Bad>
When to add complexity:
<Good>
// Start simple
const formatCurrency = (amount: number): string => {
return `$${amount.toFixed(2)}`;
};
// Requirement evolves: support multiple currencies
const formatCurrency = (amount: number, currency: string): string => {
const symbols = { USD: '$', EUR: '€', GBP: '£' };
return `${symbols[currency]}${amount.toFixed(2)}`;
};
// Requirement evolves: support localization
const formatCurrency = (amount: number, locale: string): string => {
return new Intl.NumberFormat(locale, {
style: 'currency',
currency: locale === 'en-US' ? 'USD' : 'EUR',
}).format(amount);
};Complexity added only when needed </Good>
#### Premature Abstraction
<Bad>
// One use case, but building generic framework
abstract class BaseCRUDService<T> {
abstract getAll(): Promise<T[]>;
abstract getById(id: string): Promise<T>;
abstract create(data: Partial<T>): Promise<T>;
abstract update(id: string, data: Partial<T>): Promise<T>;
abstract delete(id: string): Promise<void>;
}
class GenericRepository<T> { /*300 lines */ }
class QueryBuilder<T> { /* 200 lines*/ }
// ... building entire ORM for single table
Massive abstraction for uncertain future </Bad>
<Good>
// Simple functions for current needs
const getUsers = async (): Promise<User[]> => {
return db.query('SELECT * FROM users');
};
const getUserById = async (id: string): Promise<User | null> => {
return db.query('SELECT * FROM users WHERE id = $1', [id]);
};
// When pattern emerges across multiple entities, then abstractAbstract only when pattern proven across 3+ cases </Good>
#### Performance Optimization
<Good>
// Current: Simple approach
const filterActiveUsers = (users: User[]): User[] => {
return users.filter(user => user.isActive);
};
// Benchmark shows: 50ms for 1000 users (acceptable)
// ✓ Ship it, no optimization needed
// Later: After profiling shows this is bottleneck
// Then optimize with indexed lookup or caching
Optimize based on measurement, not assumptions </Good>
<Bad>
// Premature optimization
const filterActiveUsers = (users: User[]): User[] => {
// "This might be slow, so let's cache and index"
const cache = new WeakMap();
const indexed = buildBTreeIndex(users, 'isActive');
// 100 lines of optimization code
// Adds complexity, harder to maintain
// No evidence it was needed
};Complex solution for unmeasured problem </Bad>
#### In Practice
When implementing:
When optimizing:
When abstracting:
The Kaizen skill guides how you work. The commands provide structured analysis:
Use commands for structured problem-solving. Apply skill for day-to-day development.
Violating Continuous Improvement:
Violating Poka-Yoke:
Violating Standardized Work:
Violating Just-In-Time:
Kaizen is about:
Not about:
Mindset: Good enough today, better tomorrow. Repeat.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.