swe
SKILL.md
Software Engineering
Core Principles
| Principle | Meaning |
|---|---|
| Simplicity | Simplest code that works; complexity only when required |
| Single Responsibility | Each function/class/module does one thing |
| Self-Documenting | Code explains itself; comments are a smell |
| Fail Fast | Validate early, propagate unexpected errors |
| Test Behavior | What code does, not implementation |
| No Backwards Compat | Don't add legacy support unless requested |
| Consistency | Match project conventions over preference |
Design
SOLID
| Principle | Violation Sign |
|---|---|
| Single Responsibility | Class doing too many things |
| Open/Closed | Modifying existing code for new features |
| Liskov Substitution | Overridden methods breaking contracts |
| Interface Segregation | Clients depend on unused methods |
| Dependency Inversion | High-level imports low-level details |
Architecture
Presentation → Application → Domain ← Infrastructure
↓
Dependencies point DOWN only
Rules:
- Domain depends on nothing
- Infrastructure implements domain interfaces
- No circular dependencies
Design Patterns
Use when solving real problems, not preemptively:
| Pattern | Use When |
|---|---|
| Factory | Complex object creation |
| Builder | Many optional parameters |
| Adapter | Incompatible interfaces |
| Facade | Simplifying subsystem |
| Strategy | Runtime algorithm selection |
| Observer | Many dependents need notification |
Security
- Validate all external input (allowlists > denylists)
- Encrypt sensitive data at rest and transit
- Never log secrets
- Parameterized queries (SQL injection)
- Escape output (XSS)
Implementation
Naming
| Type | Convention | Example |
|---|---|---|
| Variables | camelCase noun | userName, isValid |
| Functions | camelCase verb | getUser, validateInput |
| Booleans | is/has/can prefix |
isActive, hasPermission |
| Constants | UPPER_SNAKE | MAX_RETRIES |
| Classes | PascalCase noun | UserService |
Rules:
- Names reveal intent
- No single-letter params
- No abbreviations (
ur→userRepository)
Self-Documenting Code
// ❌ Comment hiding bad code
if (u.r === 1 && u.s !== 0) { ... }
// ✅ Self-documenting
if (user.isAdmin && user.isActive) { ... }
Acceptable comments: RFC links, bug tracker refs, non-obvious warnings
Functions
| Do | Don't |
|---|---|
| Small, focused | God functions (100+ lines) |
| 2-3 params max | 6+ parameters |
| Return early | Deep nesting |
| Pure when possible | Hidden side effects |
| Single abstraction level | Mixed levels |
Error Handling
// ❌ Silent catch
try {
await save(user);
} catch (e) {}
// ❌ Log only
try {
await save(user);
} catch (e) {
console.log(e);
}
// ✅ Let propagate or handle specific
try {
await save(user);
} catch (e) {
if (e instanceof DuplicateEmail) return { error: "Email taken" };
throw e;
}
Rules:
- Empty catch = always wrong
- Catch only what you can handle
- Re-throw with context or propagate
- Crash visibly > fail silently
File Organization
- Match existing conventions
- No barrel files (
index.tsre-exports) - Import from concrete modules
- Co-locate tests with source
src/users/
user-service.ts
user-service.test.ts
Code Smells
| Smell | Fix |
|---|---|
| God Class | Split by responsibility |
| Feature Envy | Move method to data owner |
| Long Param List | Parameter object |
| Primitive Obsession | Value objects |
| Dead Code | Delete it |
Linting
| Tool | Purpose |
|---|---|
| Formatter | Style (Prettier, dprint) |
| Linter | Quality (ESLint, Ruff) |
| Type Checker | Safety (tsc, mypy) |
Rules:
- Automate formatting
- Zero warnings in CI
- Never disable rules—fix the code
Testing
Test Pyramid
E2E (few) - Critical journeys, slow
Integration (some) - Component interactions
Unit (many) - Fast, isolated, business logic
What to Test
| Test | Skip |
|---|---|
| Business logic | Framework code |
| Edge cases | Trivial getters |
| Error paths | Third-party libs |
| Public API | Private internals |
Test Quality
- Independent and isolated
- Deterministic (no flakiness)
- Fast (< 100ms unit)
- Single reason to fail
- Test behavior, not implementation
BDD Structure
describe("UserService", () => {
describe("given valid data", () => {
describe("when creating user", () => {
it("then persists with ID", async () => {
// arrange, act, assert
});
});
});
});
Anti-Patterns
| Pattern | Fix |
|---|---|
| Ice Cream Cone | More unit, fewer E2E |
| Flaky Tests | Fix races, use mocks |
| Testing Implementation | Test behavior |
| No Assertions | Add meaningful checks |
Review
Before PR
- Type check passes
- Lint passes
- Tests pass
- No debug/console.log
- No commented code
- Up to date with main
Review Checklist
Correctness:
- Does it work? Edge cases? Error handling?
Design:
- Right abstraction? SOLID? Dependencies appropriate?
Readability:
- Clear names? Straightforward logic? No unnecessary comments?
Security:
- Input validated? No injection? Secrets handled?
Performance:
- No N+1? No await in loops? Caching considered?
Tests:
- Sufficient coverage? Edge cases? Behavior-focused?
For Reviewers
- Code, not author
- Questions > demands
- Explain the "why"
- Blocking vs nitpick
For Authors
- Small, focused PRs
- Context in description
- Respond to all comments
Maintenance
Refactoring
- Ensure test coverage first
- Small, incremental changes
- Run tests after each change
- Refactor OR add features, never both
| Technique | When |
|---|---|
| Extract Method | Long method, reusable logic |
| Extract Class | Multiple responsibilities |
| Move Method | Uses other class's data more |
| Introduce Param Object | Long parameter lists |
Technical Debt
| Type | Handling |
|---|---|
| Deliberate | Document, schedule payback |
| Accidental | Fix when discovered |
| Bit Rot | Regular maintenance |
| Outdated Deps | Regular updates |
Find: unused code, duplicates, circular deps, outdated deps
Performance
- Don't optimize prematurely
- Measure before optimizing
- Focus on hot paths
| Pitfall | Fix |
|---|---|
| N+1 queries | Batch, joins |
| Blocking I/O | Async |
| Memory leaks | Weak refs, cleanup |
Documentation
| Document | Skip |
|---|---|
| Public APIs | Obvious code |
| ADRs | Implementation details |
| Setup/deploy | Self-documenting code |
| Non-obvious behavior | Every function |
Anti-Patterns
| Pattern | Problem | Fix |
|---|---|---|
| Big Ball of Mud | No structure | Define boundaries |
| Spaghetti Code | Tangled | Modularize |
| Lava Flow | Dead code | Delete it |
| Copy-Paste | Duplication | Extract |
| Magic Numbers | No context | Named constants |
| Circular Deps | Coupling | Abstraction layer |
| Feature Flags | Hidden complexity | One code path |
| Backwards Compat | Legacy burden | Replace entirely |
AI-Generated Debt
Code written by LLMs (including by this agent) accumulates specific debt patterns. Detect and fix on sight.
| Pattern | Description |
|---|---|
| Restating comments | Comment says what the next line does in different words |
| Boilerplate sprawl | Verbose wrappers, re-exports, adapters that add no value |
| Premature abstraction | Generic solution for a single use case |
| Convention drift | Each file follows a slightly different style |
| Cargo-cult error handling | try/catch everywhere with no actual recovery strategy |
| Orphan interfaces | Interface defined but only one implementor, no extension |
| Placeholder logic | TODO/stub/mock left behind, never replaced |
| Over-typing | Complex generics when a concrete type is clearer |
| Hallucinated API usage | Calling methods/options that don't exist in the actual lib |
| Copy-paste signatures | Same function shape repeated across files with minor changes |
Code Health Dimensions
When reviewing or writing code, assess across two axes.
Mechanical (verifiable by tools)
| Dimension | What to check |
|---|---|
| Dead code | Unused imports, exports, variables, functions |
| Duplication | Near-identical blocks across files |
| Complexity | Deep nesting, long functions, high cyclomatic count |
| Dependency | Import cycles, orphaned files, coupling violations |
| Test health | Critical paths without tests, flaky tests |
| Security | Unsanitized input, hardcoded secrets, SQL injection |
Subjective (requires judgment)
| Dimension | What to check |
|---|---|
| Naming quality | Do names communicate intent without reading the implementation? |
| Logic clarity | Can you follow control flow without mental stack overflow? |
| Error consistency | Same error strategy across modules, or a mix of patterns? |
| Abstraction fitness | Does each abstraction earn its cost with real leverage? |
| Contract coherence | Do functions honor their stated interfaces? |
| Cross-module arch | Dependency direction correct? Hub modules justified? |
| Convention consistency | Same patterns in sibling files? Or style islands? |
Prioritizing Fixes
| Tier | Effort | Examples |
|---|---|---|
| T1 | Auto-fixable | Unused imports, debug logs, formatting |
| T2 | Quick manual | Unused vars, dead exports, simple rename |
| T3 | Needs judgment | Near-duplicates, questionable abstraction |
| T4 | Major refactor | God class split, mixed-concern untangle |
Fix T1/T2 immediately. T3/T4 require a plan.
Acknowledging vs Hiding Debt
When leaving an issue unfixed:
- Document the decision - why it stays, not just that it does
- Track the cost - wontfix debt is still debt, it just has a reason
- Revisit periodically - reasons expire; what was acceptable 6 months ago may not be now
- Never dismiss to improve metrics - if the code is worse, admit it
Weekly Installs
29
Repository
knoopx/piGitHub Stars
16
First Seen
Jan 25, 2026
Security Audits
Installed on
codex29
opencode28
gemini-cli28
cursor27
claude-code26
github-copilot26