Software Engineering
Engineering judgment - thoughtful decisions - quality code.
<when_to_use>
- •Making architectural or design decisions
- •Evaluating trade-offs between approaches
- •Determining appropriate level of thoroughness
- •Assessing when code needs refactoring
- •Deciding when to ask vs proceed independently
- •Balancing speed, quality, maintainability
NOT for: mechanical tasks, clear-cut decisions, following explicit instructions
</when_to_use>
<principles>Core engineering judgment framework.
User preferences trump defaults
CLAUDE.md, project rules, existing patterns always override skill suggestions.
Simplest thing that works Start simple. Add complexity only when requirements demand.
- •Boring solutions for boring problems
- •Proven libraries over custom implementations
- •Progressive enhancement over rewrites
Read before write Understand existing patterns before modifying.
- •Check how similar features implemented
- •Follow established conventions
- •Maintain consistency
Small, focused changes One idea per commit, 20-100 LOC, 1-5 files.
- •Easy to review/understand
- •Lower bug risk
- •Simpler to revert
- •Faster feedback
Security awareness Don't introduce vulnerabilities.
- •Validate external input
- •Parameterized queries
- •Handle auth properly
- •No secrets in code/logs
Know when to stop Ship working code, don't gold-plate.
- •Implement requirements, not assumptions
- •No unrequested features
- •No speculative abstraction
<type_safety>
Type safety across languages.
Core principle: Make illegal states unrepresentable. Type system should prevent invalid data at compile time, not runtime.
Hierarchy: Correct (type-safe) - Clear (self-documenting) - Precise (not overly broad)
Key patterns:
- •Result types - Errors explicit in signatures, not hidden in exceptions
- •Discriminated unions - Mutually exclusive states with discriminator field
- •Branded types - Distinct types for domain concepts (user ID vs product ID)
- •Parse, don't validate - Transform untyped to typed at boundaries, trust types internally
See type-patterns.md for detailed concepts.
Load typescript-dev/SKILL.md for TypeScript implementations.
</type_safety>
<decision_framework>
Systematic approach to engineering choices.
Understand before deciding
- •What problem being solved?
- •What constraints exist?
- •What's already in codebase?
- •What patterns does project use?
Consider trade-offs No perfect solutions:
- •Speed vs robustness
- •Simplicity vs flexibility
- •Consistency vs optimization
- •Implement time vs maintain time
Recognize good-enough Perfect is enemy of shipped:
- •Meets requirements?
- •Maintainable by team?
- •Tested adequately?
- •Can improve incrementally?
If yes to all - ship it.
Document significant choices Non-obvious decisions: comment why, note trade-offs, link discussions, flag assumptions.
</decision_framework>
<when_to_ask>
Balance autonomy with collaboration.
Proceed independently:
- •Task clear and well-defined
- •Approach follows existing patterns
- •Changes small and localized
- •Requirements fully understood
- •No security/data integrity risks
Ask questions:
- •Requirements ambiguous
- •Multiple approaches, unclear trade-offs
- •Changes affect architecture
- •Security/compliance implications
- •Unfamiliar domain/technology
Escalate immediately:
- •Security vulnerabilities discovered
- •Data corruption/loss risk
- •Breaking changes to public APIs
- •Performance degradation detected
Don't guess on high-stakes decisions.
</when_to_ask>
<code_quality>
Standards separating good from professional code.
Type safety: Make illegal states unrepresentable via discriminated unions, branded types.
Error handling: Every error path needs explicit handling. No silent failures.
Naming: Functions=verbs (calculateTotal), variables=nouns (userId), booleans=questions (isValid).
Function design: One thing well. 10-30 lines typical, max 50. 3 params ideal, max 5. Pure when possible.
Comments: Explain why, not what.
See code-quality-patterns.md for examples.
</code_quality>
<refactoring>When and how to improve existing code.
Refactor when:
- •Adding feature reveals poor structure
- •Code duplicated 3+ times
- •Function exceeds 50 lines
- •Naming unclear/misleading
- •Tests difficult to write
Don't refactor when:
- •Code works and won't be touched
- •Time-critical delivery in progress
- •No test coverage to verify
- •Scope creep from main task
- •Just preference, no clear benefit
Guidelines:
- •Have tests first (or write them)
- •One refactoring at a time
- •Keep tests passing throughout
- •Commit refactors separately from features
- •Don't change behavior
Testing philosophy.
Test the right things:
- •Public interfaces, not implementation
- •Edge cases and error paths
- •Critical business logic
- •Integration points
- •Security boundaries
Don't over-test:
- •No tests for trivial getters/setters
- •Don't test framework behavior
- •Avoid brittle implementation-coupled tests
Coverage targets:
- •Critical paths: 90%+
- •Business logic: 80%+
- •Utility functions: 80%+
- •Overall: 70%+
Low coverage acceptable for: config, type definitions, framework boilerplate.
</testing> <performance>Balance optimization with delivery.
Premature optimization is root of evil
- •Make it work first
- •Make it right second
- •Make it fast only if needed
Optimize when:
- •Measured performance issue exists
- •User experience degraded
- •Resource costs excessive
- •Profiler shows clear bottleneck
Before optimizing:
- •Measure current performance
- •Set target metrics
- •Profile to find bottleneck
- •Optimize specific bottleneck
- •Measure improvement
- •Document trade-offs
Don't optimize based on gut feeling or without measurement.
</performance> <security>Security mindset for all code.
Input validation: Validate all external input, sanitize before processing, allowlists over blocklists.
Auth: Never trust client-side checks, verify on server, use proven libraries, don't roll your own crypto.
Data handling: Never log sensitive data, hash passwords (bcrypt/argon2), parameterized queries, strict file upload validation.
Dependencies: Keep updated, review advisories, minimize count, audit before adding.
Red flags to escalate: Payment info, user credentials, health/financial data, encryption implementation, session management.
</security><anti_patterns>
Common mistakes to avoid.
Over-engineering: Building "might need" features, premature abstraction, excessive config, enterprise patterns for simple problems. Fix: YAGNI. Build for today.
Under-engineering: No error handling, no input validation, ignoring edge cases, copy-paste over functions. Fix: Basic quality isn't optional.
Scope creep: "While I'm here...", refactoring unrelated code, adding unrequested features. Fix: Stay focused. File issues for unrelated work.
Guess-and-check: Random solutions, copying without understanding, no root cause investigation. Fix: Systematic debugging. Understand before changing.
Analysis paralysis: Endless design discussions, researching every option, waiting for perfect. Fix: Good enough + shipping > perfect + delayed.
</anti_patterns>
<communication>Senior engineer collaboration.
Clear issues/PRs: Context (problem), approach (solution), trade-offs (alternatives), testing (verification), impact (risks).
Code review: Focus on correctness/clarity/security. Suggest, don't demand perfection. Approve when good enough.
When blocked: Try 30 min self-unblock, gather context, ask specific question with context, propose solutions.
Saying no: "That would work, but have you considered X?" / "This introduces Y risk. Can we mitigate with Z?"
Back opinions with reasoning. Stay open to being wrong.
</communication><workflow_integration>
Connect with other outfitter skills.
With TDD: Senior judgment decides what's worth testing. TDD skill provides how.
With debugging: Senior judgment decides if worth fixing now. Debugging skill provides systematic investigation.
With dev- skills*: Software engineering provides the "why" and "when". dev-* skills provide the "how" for specific technologies (typescript-dev, react-dev, hono-dev, bun-dev).
</workflow_integration>
<rules>ALWAYS:
- •Read
CLAUDE.mdand project rules first - •Follow existing codebase patterns
- •Make small, focused changes
- •Validate external input
- •Handle errors explicitly
- •Test critical paths
- •Document non-obvious decisions
- •Ask when uncertain on high-stakes
NEVER:
- •Add features not in requirements
- •Ignore error handling
- •Skip input validation
- •Commit secrets or credentials
- •Guess on security decisions
- •Refactor without tests
- •Optimize without measuring
- •Over-engineer simple solutions
Complements other outfitter skills:
Core Practices:
- •tdd/SKILL.md - TDD methodology
- •debugging/SKILL.md - systematic debugging
- •pathfinding/SKILL.md - requirements clarification
Development Skills (load for implementation patterns):
- •typescript-dev/SKILL.md - TypeScript, Zod, modern features
- •react-dev/SKILL.md - React 18-19, hooks typing
- •hono-dev/SKILL.md - Hono API framework
- •bun-dev/SKILL.md - Bun runtime, SQLite, testing
Detailed Patterns:
- •type-patterns.md - language-agnostic type patterns
- •code-quality-patterns.md - code examples
Standards:
</references>