sdd-mcp-server 3.0.1 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/README.md +117 -98
  2. package/agents/architect.md +107 -0
  3. package/agents/implementer.md +154 -0
  4. package/agents/planner.md +97 -0
  5. package/agents/reviewer.md +252 -0
  6. package/agents/security-auditor.md +127 -0
  7. package/agents/tdd-guide.md +241 -0
  8. package/contexts/dev.md +58 -0
  9. package/contexts/planning.md +79 -0
  10. package/contexts/research.md +93 -0
  11. package/contexts/review.md +73 -0
  12. package/contexts/security-audit.md +92 -0
  13. package/dist/cli/install-skills.js +29 -15
  14. package/dist/cli/install-skills.js.map +1 -1
  15. package/dist/cli/migrate-steering.d.ts +24 -0
  16. package/dist/cli/migrate-steering.js +308 -0
  17. package/dist/cli/migrate-steering.js.map +1 -0
  18. package/dist/cli/sdd-mcp-cli.js +9 -0
  19. package/dist/cli/sdd-mcp-cli.js.map +1 -1
  20. package/hooks/post-tool-use/log-tool-execution.md +51 -0
  21. package/hooks/post-tool-use/update-spec-status.md +50 -0
  22. package/hooks/pre-tool-use/check-test-coverage.md +51 -0
  23. package/hooks/pre-tool-use/validate-sdd-workflow.md +55 -0
  24. package/hooks/session-end/remind-uncommitted-changes.md +58 -0
  25. package/hooks/session-end/save-session-summary.md +72 -0
  26. package/hooks/session-start/load-project-context.md +62 -0
  27. package/package.json +5 -1
  28. package/rules/coding-style.md +97 -0
  29. package/rules/error-handling.md +134 -0
  30. package/rules/git-workflow.md +92 -0
  31. package/rules/sdd-workflow.md +116 -0
  32. package/rules/security.md +89 -0
  33. package/rules/testing.md +85 -0
  34. package/sdd-entry.js +1 -1
  35. package/skills/sdd-commit/SKILL.md +0 -14
  36. package/steering/product.md +29 -0
  37. package/steering/structure.md +60 -0
  38. package/steering/tech.md +52 -0
  39. package/steering/AGENTS.md +0 -281
  40. package/steering/commit.md +0 -59
  41. package/steering/linus-review.md +0 -153
  42. package/steering/owasp-top10-check.md +0 -49
  43. package/steering/principles.md +0 -639
  44. package/steering/tdd-guideline.md +0 -324
@@ -0,0 +1,72 @@
1
+ ---
2
+ name: save-session-summary
3
+ description: Saves a summary of the session for continuity between sessions
4
+ event: session-end
5
+ priority: 100
6
+ enabled: true
7
+ ---
8
+
9
+ # Save Session Summary Hook
10
+
11
+ This hook saves a summary of the session when it ends, enabling seamless continuity in future sessions.
12
+
13
+ ## What Gets Saved
14
+
15
+ 1. **Workflow Progress**
16
+ - Features worked on during session
17
+ - Phases completed
18
+ - Tasks implemented
19
+
20
+ 2. **Decisions Made**
21
+ - Architecture decisions
22
+ - Implementation choices
23
+ - Trade-offs considered
24
+
25
+ 3. **Context to Preserve**
26
+ - Current working state
27
+ - Pending items
28
+ - Blockers or questions
29
+
30
+ ## Summary Location
31
+
32
+ ```
33
+ .spec/sessions/
34
+ └── 2024-01-15T10-30-00Z.md
35
+ ```
36
+
37
+ ## Summary Format
38
+
39
+ ```markdown
40
+ # Session Summary - 2024-01-15
41
+
42
+ ## Duration
43
+ Started: 10:30 AM | Ended: 2:45 PM (4h 15m)
44
+
45
+ ## Features Worked On
46
+
47
+ ### plugin-architecture-v3
48
+ - Completed: requirements phase approved
49
+ - In Progress: design phase
50
+ - Next: Complete component diagram
51
+
52
+ ### user-authentication
53
+ - Implemented: Tasks 1.1, 1.2, 1.3
54
+ - Tests: 12 new tests, all passing
55
+ - Blockers: Need OAuth provider decision
56
+
57
+ ## Key Decisions
58
+ 1. Using BaseManager pattern for all component managers
59
+ 2. Hooks organized by event type in nested directories
60
+ 3. YAML frontmatter for all component metadata
61
+
62
+ ## Continuation Notes
63
+ - Resume design.md at "Data Flow" section
64
+ - Review OAuth options before next session
65
+ - Run integration tests after completing design
66
+ ```
67
+
68
+ ## Benefits
69
+
70
+ - **Seamless Continuity** - Start next session with full context
71
+ - **Knowledge Preservation** - Decisions and context don't get lost
72
+ - **Progress Tracking** - Clear record of work accomplished
@@ -0,0 +1,62 @@
1
+ ---
2
+ name: load-project-context
3
+ description: Loads project context and steering documents at session start
4
+ event: session-start
5
+ priority: 100
6
+ enabled: true
7
+ ---
8
+
9
+ # Load Project Context Hook
10
+
11
+ This hook loads project-specific context and steering documents when a new session starts.
12
+
13
+ ## Actions
14
+
15
+ 1. **Detect Project Type**
16
+ - Check for `.spec/steering/` directory
17
+ - Identify project technology stack
18
+ - Load appropriate steering documents
19
+
20
+ 2. **Load Steering Documents**
21
+ ```
22
+ .spec/steering/
23
+ ├── PROJECT.md # Project overview and conventions
24
+ ├── AGENTS.md # Agent configuration
25
+ ├── ARCHITECTURE.md # System architecture
26
+ └── custom/ # Project-specific guides
27
+ ```
28
+
29
+ 3. **Restore Workflow State**
30
+ - Read `.spec/specs/*/spec.json` for active features
31
+ - Identify current phase for each feature
32
+ - Surface any incomplete workflows
33
+
34
+ 4. **Set Session Context**
35
+ - Configure AI persona based on active agent
36
+ - Apply relevant rules
37
+ - Activate appropriate context mode
38
+
39
+ ## Session Initialization Message
40
+
41
+ ```
42
+ 📋 Project Context Loaded
43
+
44
+ Project: sdd-mcp
45
+ Type: Node.js/TypeScript
46
+ Active Features:
47
+ • plugin-architecture-v3 (design phase)
48
+ • user-authentication (implementation phase)
49
+
50
+ Steering Documents:
51
+ ✓ PROJECT.md loaded
52
+ ✓ AGENTS.md loaded
53
+ ✓ 3 custom guides loaded
54
+
55
+ Ready to continue. Run /sdd-status for full workflow state.
56
+ ```
57
+
58
+ ## Benefits
59
+
60
+ - **Consistent Context** - Every session starts with full project understanding
61
+ - **Workflow Continuity** - Pick up where you left off
62
+ - **Best Practices** - Steering documents are always active
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sdd-mcp-server",
3
- "version": "3.0.1",
3
+ "version": "3.1.0",
4
4
  "description": "MCP server for spec-driven development workflows across AI-agent CLIs and IDEs",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -12,6 +12,10 @@
12
12
  "dist/**/*",
13
13
  "skills/**/*",
14
14
  "steering/**/*",
15
+ "rules/**/*",
16
+ "contexts/**/*",
17
+ "agents/**/*",
18
+ "hooks/**/*",
15
19
  "sdd-entry.js",
16
20
  "mcp-server.js",
17
21
  "atomicWrite.js",
@@ -0,0 +1,97 @@
1
+ ---
2
+ name: coding-style
3
+ description: Enforce consistent TypeScript/JavaScript coding conventions and design principles
4
+ priority: 100
5
+ alwaysActive: true
6
+ ---
7
+
8
+ # Coding Style Rules
9
+
10
+ ## TypeScript/JavaScript Guidelines
11
+
12
+ ### Type Safety
13
+ - Use explicit types for function parameters and return values
14
+ - Avoid `any` type - use `unknown` or proper generics instead
15
+ - Enable strict mode in TypeScript configuration
16
+
17
+ ### Naming Conventions
18
+ - **Classes**: PascalCase (e.g., `UserService`)
19
+ - **Functions/Methods**: camelCase (e.g., `getUserById`)
20
+ - **Constants**: UPPER_SNAKE_CASE (e.g., `MAX_RETRIES`)
21
+ - **Files**: kebab-case (e.g., `user-service.ts`)
22
+
23
+ ### Functions
24
+ - Keep functions small and focused (single responsibility)
25
+ - Limit function parameters to 3-4; use options object for more
26
+ - Use early returns to reduce nesting
27
+
28
+ ### Code Organization
29
+ - One class per file (with rare exceptions)
30
+ - Keep files under 300 lines when possible
31
+ - Write self-documenting code - minimize inline comments
32
+
33
+ ---
34
+
35
+ # Core Design Principles
36
+
37
+ **Golden Rule**: Always ask "Does this code follow SOLID, DRY, KISS, YAGNI?" before committing.
38
+
39
+ ## SOLID Principles
40
+
41
+ ### S - Single Responsibility Principle (SRP)
42
+ A class/module should have one, and only one, reason to change.
43
+
44
+ ### O - Open/Closed Principle (OCP)
45
+ Open for extension, closed for modification. Use interfaces/abstractions.
46
+
47
+ ### L - Liskov Substitution Principle (LSP)
48
+ Derived classes must be substitutable for their base classes.
49
+
50
+ ### I - Interface Segregation Principle (ISP)
51
+ No client should depend on methods it doesn't use. Keep interfaces small.
52
+
53
+ ### D - Dependency Inversion Principle (DIP)
54
+ Depend on abstractions, not concrete implementations. Use dependency injection.
55
+
56
+ ## DRY (Don't Repeat Yourself)
57
+ Every piece of knowledge should have a single, authoritative representation.
58
+
59
+ ## KISS (Keep It Simple)
60
+ Simplicity should be a key goal. Avoid unnecessary complexity.
61
+
62
+ ## YAGNI (You Aren't Gonna Need It)
63
+ Don't implement functionality until it's actually needed.
64
+
65
+ ---
66
+
67
+ ## Code Review Checklist
68
+
69
+ ### SOLID
70
+ - [ ] Does each class/module have a single responsibility?
71
+ - [ ] Can I extend functionality without modifying existing code?
72
+ - [ ] Are interfaces small and focused?
73
+ - [ ] Do dependencies point toward abstractions?
74
+
75
+ ### DRY
76
+ - [ ] Is there any duplicated logic that should be extracted?
77
+ - [ ] Are magic numbers/strings extracted to constants?
78
+
79
+ ### KISS
80
+ - [ ] Is the solution as simple as possible?
81
+ - [ ] Are variable/function names clear without comments?
82
+
83
+ ### YAGNI
84
+ - [ ] Is every feature actually needed now?
85
+ - [ ] Are there "future-proofing" additions that can be removed?
86
+
87
+ ---
88
+
89
+ ## Common Anti-Patterns to Avoid
90
+
91
+ | Anti-Pattern | Violates | Fix |
92
+ |--------------|----------|-----|
93
+ | God Object/Class | SRP | Split into focused classes |
94
+ | Copy-Paste Programming | DRY | Extract common logic |
95
+ | Premature Optimization | KISS, YAGNI | Optimize when needed |
96
+ | Long Parameter List | KISS | Use parameter objects |
97
+ | Magic Numbers | DRY | Extract to named constants |
@@ -0,0 +1,134 @@
1
+ ---
2
+ name: error-handling
3
+ description: Error handling patterns and best practices
4
+ priority: 90
5
+ alwaysActive: true
6
+ ---
7
+
8
+ # Error Handling Rules
9
+
10
+ ## Error Types
11
+
12
+ ### Custom Error Classes
13
+ Define domain-specific errors for better handling:
14
+
15
+ ```typescript
16
+ class ValidationError extends Error {
17
+ constructor(message: string, public field?: string) {
18
+ super(message);
19
+ this.name = 'ValidationError';
20
+ }
21
+ }
22
+
23
+ class NotFoundError extends Error {
24
+ constructor(resource: string, id: string) {
25
+ super(`${resource} with id "${id}" not found`);
26
+ this.name = 'NotFoundError';
27
+ }
28
+ }
29
+
30
+ class AuthorizationError extends Error {
31
+ constructor(action: string) {
32
+ super(`Not authorized to ${action}`);
33
+ this.name = 'AuthorizationError';
34
+ }
35
+ }
36
+ ```
37
+
38
+ ## Error Handling Patterns
39
+
40
+ ### Try-Catch Best Practices
41
+ ```typescript
42
+ // Good: Specific error handling
43
+ try {
44
+ await saveUser(user);
45
+ } catch (error) {
46
+ if (error instanceof ValidationError) {
47
+ return { status: 400, message: error.message };
48
+ }
49
+ if (error instanceof DuplicateError) {
50
+ return { status: 409, message: 'User already exists' };
51
+ }
52
+ // Re-throw unexpected errors
53
+ throw error;
54
+ }
55
+
56
+ // Bad: Swallowing all errors
57
+ try {
58
+ await saveUser(user);
59
+ } catch (error) {
60
+ console.log('Something went wrong');
61
+ // Error lost, no recovery, no logging
62
+ }
63
+ ```
64
+
65
+ ### Async Error Handling
66
+ ```typescript
67
+ // Always use try-catch with async/await
68
+ async function fetchData(): Promise<Data> {
69
+ try {
70
+ const response = await fetch(url);
71
+ if (!response.ok) {
72
+ throw new HttpError(response.status, response.statusText);
73
+ }
74
+ return await response.json();
75
+ } catch (error) {
76
+ logger.error('Failed to fetch data', { error, url });
77
+ throw error;
78
+ }
79
+ }
80
+ ```
81
+
82
+ ### Error Propagation
83
+ - Let errors bubble up to appropriate handlers
84
+ - Add context when re-throwing
85
+ - Don't catch errors you can't handle
86
+
87
+ ```typescript
88
+ // Good: Add context when re-throwing
89
+ async function processOrder(orderId: string): Promise<void> {
90
+ try {
91
+ await validateOrder(orderId);
92
+ await chargePayment(orderId);
93
+ await fulfillOrder(orderId);
94
+ } catch (error) {
95
+ throw new OrderProcessingError(
96
+ `Failed to process order ${orderId}`,
97
+ { cause: error }
98
+ );
99
+ }
100
+ }
101
+ ```
102
+
103
+ ## Logging Errors
104
+
105
+ ### What to Log
106
+ - Error message and stack trace
107
+ - Request/operation context
108
+ - User identifier (not PII)
109
+ - Timestamp
110
+
111
+ ### What NOT to Log
112
+ - Passwords or tokens
113
+ - Personal identifiable information (PII)
114
+ - Full credit card numbers
115
+ - Internal implementation details in production
116
+
117
+ ### Log Levels
118
+ - **ERROR**: Unexpected failures requiring attention
119
+ - **WARN**: Handled issues that may indicate problems
120
+ - **INFO**: Normal operations, significant events
121
+ - **DEBUG**: Detailed information for troubleshooting
122
+
123
+ ## User-Facing Errors
124
+
125
+ ### Never Expose
126
+ - Stack traces
127
+ - Database errors
128
+ - Internal paths
129
+ - Implementation details
130
+
131
+ ### Always Provide
132
+ - Clear, actionable message
133
+ - Error code for support reference
134
+ - Next steps when possible
@@ -0,0 +1,92 @@
1
+ ---
2
+ name: git-workflow
3
+ description: Git commit and branching conventions
4
+ priority: 80
5
+ alwaysActive: true
6
+ ---
7
+
8
+ # Git Workflow Rules
9
+
10
+ ## Commit Messages
11
+
12
+ ### Format
13
+ ```
14
+ <type>(<scope>): <subject>
15
+
16
+ <body>
17
+
18
+ <footer>
19
+ ```
20
+
21
+ ### Types
22
+ - **feat**: New feature
23
+ - **fix**: Bug fix
24
+ - **docs**: Documentation only changes
25
+ - **style**: Code style changes (formatting, semicolons)
26
+ - **refactor**: Code change that neither fixes a bug nor adds a feature
27
+ - **perf**: Performance improvement
28
+ - **test**: Adding or updating tests
29
+ - **chore**: Build process or auxiliary tool changes
30
+
31
+ ### Subject Line
32
+ - Use imperative mood ("add" not "added")
33
+ - No period at the end
34
+ - Maximum 50 characters
35
+ - Capitalize first letter
36
+
37
+ ### Body
38
+ - Explain "what" and "why", not "how"
39
+ - Wrap at 72 characters
40
+ - Separate from subject with blank line
41
+
42
+ ### Examples
43
+ ```
44
+ feat(auth): add JWT token refresh endpoint
45
+
46
+ Implement automatic token refresh to improve user experience.
47
+ Tokens are refreshed 5 minutes before expiration.
48
+
49
+ Closes #123
50
+ ```
51
+
52
+ ```
53
+ fix(api): handle null response from external service
54
+
55
+ The external payment API occasionally returns null instead of
56
+ an error object. This caused unhandled exceptions in production.
57
+
58
+ Fixes #456
59
+ ```
60
+
61
+ ## Branching Strategy
62
+
63
+ ### Branch Types
64
+ - **main/master**: Production-ready code
65
+ - **develop**: Integration branch for features
66
+ - **feature/**: New features (`feature/add-user-auth`)
67
+ - **fix/**: Bug fixes (`fix/login-validation`)
68
+ - **refactor/**: Code refactoring (`refactor/better-architecture`)
69
+
70
+ ### Branch Naming
71
+ - Use lowercase with hyphens
72
+ - Include ticket number if applicable
73
+ - Keep names descriptive but concise
74
+
75
+ ## Pull Requests
76
+
77
+ ### Before Creating PR
78
+ - Rebase on latest target branch
79
+ - Run all tests locally
80
+ - Update documentation if needed
81
+ - Self-review your changes
82
+
83
+ ### PR Description
84
+ - Reference related issues
85
+ - Describe what changed and why
86
+ - Include testing instructions
87
+ - Add screenshots for UI changes
88
+
89
+ ### Review Process
90
+ - Address all review comments
91
+ - Don't force-push after review started
92
+ - Squash commits when merging (if team policy)
@@ -0,0 +1,116 @@
1
+ ---
2
+ name: sdd-workflow
3
+ description: Spec-Driven Development process rules
4
+ priority: 85
5
+ alwaysActive: true
6
+ ---
7
+
8
+ # SDD Workflow Rules
9
+
10
+ ## Spec-Driven Development Process
11
+
12
+ ### Phase Order
13
+ Follow the SDD phases in strict order:
14
+
15
+ 1. **Initialize** (`sdd-init`)
16
+ - Define feature name and description
17
+ - Answer clarification questions
18
+ - Create spec directory structure
19
+
20
+ 2. **Requirements** (`sdd-requirements`)
21
+ - Generate EARS-formatted requirements
22
+ - Define acceptance criteria
23
+ - Identify constraints and assumptions
24
+
25
+ 3. **Design** (`sdd-design`)
26
+ - Create technical design specifications
27
+ - Define component architecture
28
+ - Document interfaces and data flows
29
+
30
+ 4. **Tasks** (`sdd-tasks`)
31
+ - Break down into implementable tasks
32
+ - Apply TDD methodology
33
+ - Estimate complexity
34
+
35
+ 5. **Implement** (`sdd-implement`)
36
+ - Follow TDD (Red-Green-Refactor)
37
+ - Reference steering documents
38
+ - Update spec status
39
+
40
+ ## EARS Requirements Format
41
+
42
+ Use Easy Approach to Requirements Syntax:
43
+
44
+ | Pattern | Template | Use Case |
45
+ |---------|----------|----------|
46
+ | Ubiquitous | The `<system>` SHALL `<action>` | Always true |
47
+ | Event-Driven | WHEN `<trigger>` THEN the `<system>` SHALL `<action>` | Response to event |
48
+ | State-Driven | WHILE `<state>` THE `<system>` SHALL `<action>` | During state |
49
+ | Optional | WHERE `<feature>` THE `<system>` SHALL `<action>` | Configurable |
50
+ | Unwanted | IF `<condition>` THEN the `<system>` SHALL `<action>` | Exception |
51
+
52
+ ### Example
53
+ ```markdown
54
+ ## FR-1: User Authentication
55
+ WHEN a user submits valid credentials
56
+ THEN the system SHALL authenticate the user and return a session token
57
+
58
+ **Acceptance Criteria:**
59
+ 1. Token expires after 24 hours of inactivity
60
+ 2. Invalid credentials return 401 error
61
+ 3. Rate limiting prevents brute force attempts
62
+ ```
63
+
64
+ ## Steering Documents
65
+
66
+ ### Always Reference
67
+ - `.spec/steering/tdd-guideline.md` - TDD methodology
68
+ - `.spec/steering/principles.md` - SOLID, DRY, KISS, YAGNI
69
+ - `.spec/steering/linus-review.md` - Code review standards
70
+
71
+ ### When to Reference
72
+ - Before writing any code, review relevant steering docs
73
+ - During code review, verify compliance
74
+ - When refactoring, ensure principles are maintained
75
+
76
+ ## Approval Gates
77
+
78
+ ### Requirements Approval
79
+ Before proceeding to design:
80
+ - [ ] All requirements use EARS format
81
+ - [ ] Each requirement is testable
82
+ - [ ] Acceptance criteria are specific
83
+ - [ ] Constraints are documented
84
+
85
+ ### Design Approval
86
+ Before proceeding to tasks:
87
+ - [ ] Architecture diagram included
88
+ - [ ] Interfaces defined
89
+ - [ ] Dependencies identified
90
+ - [ ] Security considerations addressed
91
+
92
+ ### Tasks Approval
93
+ Before proceeding to implementation:
94
+ - [ ] Tasks follow TDD structure
95
+ - [ ] Complexity estimated
96
+ - [ ] Dependencies mapped
97
+ - [ ] Steering doc references included
98
+
99
+ ## Spec File Locations
100
+
101
+ ```
102
+ .spec/
103
+ ├── steering/ # Project-wide rules
104
+ │ ├── product.md
105
+ │ ├── tech.md
106
+ │ ├── structure.md
107
+ │ ├── tdd-guideline.md
108
+ │ ├── principles.md
109
+ │ └── linus-review.md
110
+ └── specs/ # Feature specifications
111
+ └── {feature-name}/
112
+ ├── spec.json
113
+ ├── requirements.md
114
+ ├── design.md
115
+ └── tasks.md
116
+ ```
@@ -0,0 +1,89 @@
1
+ ---
2
+ name: security
3
+ description: Security best practices aligned with OWASP Top 10
4
+ priority: 99
5
+ alwaysActive: true
6
+ ---
7
+
8
+ # Security Rules
9
+
10
+ ## OWASP Top 10 Alignment
11
+
12
+ ### A01: Broken Access Control
13
+ - Implement proper authentication checks before sensitive operations
14
+ - Use principle of least privilege for permissions
15
+ - Validate user authorization for every request
16
+ - Never expose internal IDs directly to users
17
+
18
+ ### A02: Cryptographic Failures
19
+ - Never store passwords in plain text - use bcrypt or similar
20
+ - Use HTTPS for all external communications
21
+ - Don't hardcode secrets in source code
22
+ - Use secure random number generators for tokens
23
+
24
+ ### A03: Injection
25
+ - Always use parameterized queries for database operations
26
+ - Validate and sanitize all user inputs
27
+ - Escape output data appropriately for context (HTML, SQL, etc.)
28
+ - Never use `eval()` or similar dynamic code execution
29
+
30
+ ### A04: Insecure Design
31
+ - Apply defense in depth - multiple layers of security
32
+ - Implement rate limiting for APIs
33
+ - Design with security in mind from the start
34
+ - Use secure defaults
35
+
36
+ ### A05: Security Misconfiguration
37
+ - Disable unnecessary features and services
38
+ - Keep dependencies updated
39
+ - Remove default credentials
40
+ - Configure proper error handling (no stack traces in production)
41
+
42
+ ### A06: Vulnerable Components
43
+ - Regularly audit and update dependencies
44
+ - Use `npm audit` or similar tools
45
+ - Pin dependency versions in production
46
+ - Monitor security advisories
47
+
48
+ ### A07: Authentication Failures
49
+ - Implement strong password policies
50
+ - Use multi-factor authentication where possible
51
+ - Protect against brute force attacks
52
+ - Secure session management
53
+
54
+ ### A08: Data Integrity Failures
55
+ - Validate data integrity with checksums
56
+ - Use code signing for releases
57
+ - Verify software updates are from trusted sources
58
+
59
+ ### A09: Logging Failures
60
+ - Log security-relevant events
61
+ - Never log sensitive data (passwords, tokens, PII)
62
+ - Ensure logs are tamper-proof
63
+ - Monitor logs for suspicious activity
64
+
65
+ ### A10: Server-Side Request Forgery (SSRF)
66
+ - Validate and sanitize URLs before making requests
67
+ - Use allowlists for external services
68
+ - Don't expose internal services to user-controlled URLs
69
+
70
+ ## Code Security Practices
71
+
72
+ ### Input Validation
73
+ ```typescript
74
+ // Always validate user input
75
+ function processUserInput(input: unknown): ValidatedInput {
76
+ if (typeof input !== 'string') {
77
+ throw new ValidationError('Input must be a string');
78
+ }
79
+ if (input.length > MAX_INPUT_LENGTH) {
80
+ throw new ValidationError('Input too long');
81
+ }
82
+ return sanitize(input);
83
+ }
84
+ ```
85
+
86
+ ### Error Handling
87
+ - Never expose internal errors to users
88
+ - Log errors with context for debugging
89
+ - Return generic error messages to clients