Code Development Skill
This skill provides a structured approach to coding tasks with emphasis on quality, security, and maintainability.
When to Use This Skill
Use this skill for any coding task including:
- Implementing new features or functionality
- Fixing bugs or issues
- Refactoring existing code
- Optimizing performance
- Adding or modifying tests
- Making any changes to source code
Core Development Workflow
1. Understand Before Coding
Before making changes:
- Read relevant existing code to understand current implementation
- Identify the scope of changes needed
- Ground requirements and invariants in the user's latest explicit decisions,
current authoritative contracts, and actual enforcement boundaries
- Consider edge cases and potential side effects
- Check for existing patterns and conventions in the codebase
- Choose the smallest complete implementation; do not invent requirements,
compatibility layers, configuration knobs, or speculative abstractions
2. Plan the Implementation
For non-trivial tasks:
- Use TodoWrite to break down the work into clear steps
- Identify files that need to be modified
- Consider the order of operations (e.g., tests before implementation, or vice versa)
- Plan for both happy path and error handling
- Identify every test or end-to-end outcome the user explicitly requested and
the real runtime, credentials, or infrastructure needed to verify it
- Identify new components that need user-facing documentation and temporary
implementation paths that need an explicit removal condition
3. Write Quality Code
Follow these principles:
Code Style & Conventions:
- Follow existing code style and patterns in the codebase
- Use spaces not tabs (per user configuration)
- Choose descriptive variable and function names
- Keep functions focused and single-purpose
- Add comments for complex logic, but prefer self-documenting code
- Reuse existing architecture and one canonical source of truth; remove
unnecessary helpers, state machinery, duplicate configuration, and defenses
not required by a real current contract
Documentation and Deferred Work:
- When introducing a component, load
$docy guidance and add or update its
user-facing guide in the same change. Cover its purpose, setup, configuration,
supported boundaries, verification, and troubleshooting.
- Update relevant README links, navigation, and adjacent documents that would
otherwise describe outdated behavior.
- Keep active specifications and user-facing documentation synchronized with
implemented behavior, approved limitations, and remaining verification gaps.
- Mark temporary placeholders, compatibility drains, feature filters, or
deferred behavior with a nearby concise
TODO naming the missing capability,
responsible milestone or owner, and replacement or removal condition.
- Explicitly mark temporary authentication, credential, transport, or network
exceptions beside their implementation and explain their replacement path.
- Keep permanent security boundaries and intentional architecture free of
misleading temporary markers.
Security Considerations:
- NEVER introduce security vulnerabilities
- Watch for: command injection, XSS, SQL injection, path traversal, insecure deserialization
- Validate and sanitize all user inputs
- Use parameterized queries for database operations
- Avoid hardcoding secrets or credentials
- Use secure defaults and principle of least privilege
- For detailed security guidance, consult
./references/security-guidelines.md
Error Handling:
- Handle errors gracefully with appropriate error messages
- Avoid exposing sensitive information in error messages
- Clean up resources properly (close files, connections, etc.)
- Consider failure modes and recovery strategies
Performance:
- Avoid unnecessary computations or database queries
- Consider time and space complexity for data structures and algorithms
- Use caching appropriately
- Profile before optimizing (don't prematurely optimize)
4. Testing
Prefer integration tests over unit tests. Integration tests:
- Test the full application as users would interact with it
- Catch more bugs (import issues, config problems, integration bugs)
- Are easier to maintain during refactoring
- Provide confidence that the actual user experience works
When changing program behavior:
- Add tests (per user configuration)
- Write integration tests first - test the full application/CLI
- Run the actual application process, don't import functions directly
- Write tests that cover both happy path and edge cases
- Ensure existing tests still pass
- Add unit tests sparingly - only for complex logic that needs isolation
- Test error handling and boundary conditions
- Use the repository's existing test runner and conventions; do not introduce
Jest, snapshots, dependencies, or snapshot updates unless the repository and
requested behavior actually require them
- Exercise supported routes, realistic ownership and persisted state, real
authorization, and observable outcomes at their authoritative boundary
- Reject tests that assert behavior invented by their own mocks, monkeypatches,
fixtures, adapters, nonexistent endpoints, or impossible application states
- Add concise comments before non-obvious integration setup and assertions to
explain the scenario and the business or security invariant being verified
- Distinguish real runtime or infrastructure execution from rendering-only
checks, substitutes, and skipped cases; report unavailable prerequisites
honestly instead of presenting a substitute as equivalent proof
- Run every test the user explicitly requested. If any requested test fails,
skips, or cannot run, report that exact acceptance criterion as unverified
and do not claim the requested outcome is complete
Test-driven development approach:
- Write failing integration test first (recommended)
- Implement the minimal code to make tests pass
- Refactor while keeping tests green
- Add unit tests only if needed for complex logic
For detailed testing guidance, consult ./references/testing-guidelines.md
5. Review Your Work
Before marking a task complete:
- Re-read the changes you made
- Check for introduced bugs or regressions
- Verify security considerations are addressed
- Ensure tests pass
- Confirm each user-requested test actually ran and passed at the requested
boundary; name any remaining infrastructure or acceptance-proof blocker
- Verify new component documentation, its links and examples, and explanations
for every intentionally temporary implementation path
- Look for opportunities to simplify
- Remove debug code, console.logs, or temporary changes
6. Iterate and Improve
If errors or issues arise:
- Don't mark tasks as complete if there are failures
- Debug systematically (check error messages, add logging, isolate the issue)
- Fix the root cause, not just symptoms
- Verify the fix works with tests
Common Patterns
When Editing Files
- Always use Read before Edit or Write
- Preserve exact indentation when using Edit tool
- Use Edit for targeted changes, Write for new files or complete rewrites
When Searching Code
- Use Grep for content search
- Use Glob for finding files by pattern
- Use Task tool with Explore agent for open-ended exploration
When Working with Git
- Check git status before committing
- Write clear, concise commit messages
- Don't commit secrets, credentials, or sensitive data
- Follow the repository's commit message conventions
Anti-Patterns to Avoid
- Don't write code without reading existing implementation
- Don't mark tasks complete when tests are failing
- Don't skip error handling or edge cases
- Don't introduce security vulnerabilities
- Don't hardcode values that should be configurable
- Don't duplicate code instead of extracting common functionality
- Don't leave commented-out code or debug statements
- Don't make changes without understanding the full impact
Language-Specific Considerations
When working in different languages, adapt to their idioms and best practices:
JavaScript/TypeScript:
- Use const/let, never var
- Prefer async/await over raw promises
- Handle promise rejections
- Use TypeScript types effectively
- Use the repository's existing test framework and scripts
- Write integration tests that run the actual CLI/application process
Python:
- Follow PEP 8 style guidelines
- Use type hints for better code clarity
- Properly handle exceptions with try/except
- Use context managers (with statements) for resources
Go:
- Handle errors explicitly (don't ignore them)
- Use defer for cleanup
- Follow Go conventions (e.g., early returns)
Rust:
- Handle Result and Option types properly
- Use borrowing and ownership correctly
- Leverage the type system for safety
Java:
- Use appropriate exception handling
- Follow naming conventions (camelCase for methods/variables, PascalCase for classes)
- Properly close resources (use try-with-resources)
Best Practices Summary
- Read first, code second - Understand before changing
- Security by default - Never introduce vulnerabilities
- Test your changes - Write integration tests first, unit tests sparingly
- Follow conventions - Match the existing codebase style
- Handle errors properly - Don't let exceptions crash the system
- Review before submitting - Catch issues early
- Iterate on feedback - Fix problems until tests pass
For more detailed information on specific topics:
- Security best practices:
./references/security-guidelines.md
- Testing strategies:
./references/testing-guidelines.md
1---2name: dev-code3description: Implement, fix, refactor, or otherwise modify source code.4---56# Code Development Skill78This skill provides a structured approach to coding tasks with emphasis on quality, security, and maintainability.910## When to Use This Skill1112Use this skill for any coding task including:13- Implementing new features or functionality14- Fixing bugs or issues15- Refactoring existing code16- Optimizing performance17- Adding or modifying tests18- Making any changes to source code1920## Core Development Workflow2122### 1. Understand Before Coding2324Before making changes:25- Read relevant existing code to understand current implementation26- Identify the scope of changes needed27- Ground requirements and invariants in the user's latest explicit decisions,28 current authoritative contracts, and actual enforcement boundaries29- Consider edge cases and potential side effects30- Check for existing patterns and conventions in the codebase31- Choose the smallest complete implementation; do not invent requirements,32 compatibility layers, configuration knobs, or speculative abstractions3334### 2. Plan the Implementation3536For non-trivial tasks:37- Use TodoWrite to break down the work into clear steps38- Identify files that need to be modified39- Consider the order of operations (e.g., tests before implementation, or vice versa)40- Plan for both happy path and error handling41- Identify every test or end-to-end outcome the user explicitly requested and42 the real runtime, credentials, or infrastructure needed to verify it43- Identify new components that need user-facing documentation and temporary44 implementation paths that need an explicit removal condition4546### 3. Write Quality Code4748Follow these principles:4950**Code Style & Conventions:**51- Follow existing code style and patterns in the codebase52- Use spaces not tabs (per user configuration)53- Choose descriptive variable and function names54- Keep functions focused and single-purpose55- Add comments for complex logic, but prefer self-documenting code56- Reuse existing architecture and one canonical source of truth; remove57 unnecessary helpers, state machinery, duplicate configuration, and defenses58 not required by a real current contract5960**Documentation and Deferred Work:**61- When introducing a component, load `$docy` guidance and add or update its62 user-facing guide in the same change. Cover its purpose, setup, configuration,63 supported boundaries, verification, and troubleshooting.64- Update relevant README links, navigation, and adjacent documents that would65 otherwise describe outdated behavior.66- Keep active specifications and user-facing documentation synchronized with67 implemented behavior, approved limitations, and remaining verification gaps.68- Mark temporary placeholders, compatibility drains, feature filters, or69 deferred behavior with a nearby concise `TODO` naming the missing capability,70 responsible milestone or owner, and replacement or removal condition.71- Explicitly mark temporary authentication, credential, transport, or network72 exceptions beside their implementation and explain their replacement path.73- Keep permanent security boundaries and intentional architecture free of74 misleading temporary markers.7576**Security Considerations:**77- NEVER introduce security vulnerabilities78- Watch for: command injection, XSS, SQL injection, path traversal, insecure deserialization79- Validate and sanitize all user inputs80- Use parameterized queries for database operations81- Avoid hardcoding secrets or credentials82- Use secure defaults and principle of least privilege83- For detailed security guidance, consult `./references/security-guidelines.md`8485**Error Handling:**86- Handle errors gracefully with appropriate error messages87- Avoid exposing sensitive information in error messages88- Clean up resources properly (close files, connections, etc.)89- Consider failure modes and recovery strategies9091**Performance:**92- Avoid unnecessary computations or database queries93- Consider time and space complexity for data structures and algorithms94- Use caching appropriately95- Profile before optimizing (don't prematurely optimize)9697### 4. Testing9899**Prefer integration tests over unit tests.** Integration tests:100- Test the full application as users would interact with it101- Catch more bugs (import issues, config problems, integration bugs)102- Are easier to maintain during refactoring103- Provide confidence that the actual user experience works104105When changing program behavior:106- Add tests (per user configuration)107- **Write integration tests first** - test the full application/CLI108- Run the actual application process, don't import functions directly109- Write tests that cover both happy path and edge cases110- Ensure existing tests still pass111- Add unit tests sparingly - only for complex logic that needs isolation112- Test error handling and boundary conditions113- Use the repository's existing test runner and conventions; do not introduce114 Jest, snapshots, dependencies, or snapshot updates unless the repository and115 requested behavior actually require them116- Exercise supported routes, realistic ownership and persisted state, real117 authorization, and observable outcomes at their authoritative boundary118- Reject tests that assert behavior invented by their own mocks, monkeypatches,119 fixtures, adapters, nonexistent endpoints, or impossible application states120- Add concise comments before non-obvious integration setup and assertions to121 explain the scenario and the business or security invariant being verified122- Distinguish real runtime or infrastructure execution from rendering-only123 checks, substitutes, and skipped cases; report unavailable prerequisites124 honestly instead of presenting a substitute as equivalent proof125- Run every test the user explicitly requested. If any requested test fails,126 skips, or cannot run, report that exact acceptance criterion as unverified127 and do not claim the requested outcome is complete128129Test-driven development approach:1301. Write failing integration test first (recommended)1312. Implement the minimal code to make tests pass1323. Refactor while keeping tests green1334. Add unit tests only if needed for complex logic134135For detailed testing guidance, consult `./references/testing-guidelines.md`136137### 5. Review Your Work138139Before marking a task complete:140- Re-read the changes you made141- Check for introduced bugs or regressions142- Verify security considerations are addressed143- Ensure tests pass144- Confirm each user-requested test actually ran and passed at the requested145 boundary; name any remaining infrastructure or acceptance-proof blocker146- Verify new component documentation, its links and examples, and explanations147 for every intentionally temporary implementation path148- Look for opportunities to simplify149- Remove debug code, console.logs, or temporary changes150151### 6. Iterate and Improve152153If errors or issues arise:154- Don't mark tasks as complete if there are failures155- Debug systematically (check error messages, add logging, isolate the issue)156- Fix the root cause, not just symptoms157- Verify the fix works with tests158159## Common Patterns160161### When Editing Files162- Always use Read before Edit or Write163- Preserve exact indentation when using Edit tool164- Use Edit for targeted changes, Write for new files or complete rewrites165166### When Searching Code167- Use Grep for content search168- Use Glob for finding files by pattern169- Use Task tool with Explore agent for open-ended exploration170171### When Working with Git172- Check git status before committing173- Write clear, concise commit messages174- Don't commit secrets, credentials, or sensitive data175- Follow the repository's commit message conventions176177## Anti-Patterns to Avoid178179- **Don't** write code without reading existing implementation180- **Don't** mark tasks complete when tests are failing181- **Don't** skip error handling or edge cases182- **Don't** introduce security vulnerabilities183- **Don't** hardcode values that should be configurable184- **Don't** duplicate code instead of extracting common functionality185- **Don't** leave commented-out code or debug statements186- **Don't** make changes without understanding the full impact187188## Language-Specific Considerations189190When working in different languages, adapt to their idioms and best practices:191192**JavaScript/TypeScript:**193- Use const/let, never var194- Prefer async/await over raw promises195- Handle promise rejections196- Use TypeScript types effectively197- Use the repository's existing test framework and scripts198- Write integration tests that run the actual CLI/application process199200**Python:**201- Follow PEP 8 style guidelines202- Use type hints for better code clarity203- Properly handle exceptions with try/except204- Use context managers (with statements) for resources205206**Go:**207- Handle errors explicitly (don't ignore them)208- Use defer for cleanup209- Follow Go conventions (e.g., early returns)210211**Rust:**212- Handle Result and Option types properly213- Use borrowing and ownership correctly214- Leverage the type system for safety215216**Java:**217- Use appropriate exception handling218- Follow naming conventions (camelCase for methods/variables, PascalCase for classes)219- Properly close resources (use try-with-resources)220221## Best Practices Summary2222231. **Read first, code second** - Understand before changing2242. **Security by default** - Never introduce vulnerabilities2253. **Test your changes** - Write integration tests first, unit tests sparingly2264. **Follow conventions** - Match the existing codebase style2275. **Handle errors properly** - Don't let exceptions crash the system2286. **Review before submitting** - Catch issues early2297. **Iterate on feedback** - Fix problems until tests pass230231For more detailed information on specific topics:232- Security best practices: `./references/security-guidelines.md`233- Testing strategies: `./references/testing-guidelines.md`