feat(docs): add development methodologies documentation v3.5.0

- Add guide/methodologies.md: index of 15 methodologies with decision tree
- Add guide/workflows/: 4 practical workflow guides
  - tdd-with-claude.md: TDD with Claude-specific patterns
  - spec-first.md: SDD adapted for CLAUDE.md
  - plan-driven.md: effective /plan mode usage
  - iterative-refinement.md: prompt→feedback→reprompt loops
- Add Section 9.14 in ultimate-guide.md linking to workflows
- Update guide/README.md with new documentation
- Bump version 3.4.0 → 3.5.0 across all files

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Florian BRUNIAUX 2026-01-14 22:28:02 +01:00
parent f9044e2deb
commit f7551037fe
11 changed files with 1638 additions and 5 deletions

View file

@ -0,0 +1,312 @@
# Iterative Refinement
> **Confidence**: Tier 2 — Validated pattern observed across many Claude Code users.
Prompt, observe, reprompt until satisfied. The core loop of effective AI-assisted development.
---
## Table of Contents
1. [TL;DR](#tldr)
2. [The Loop](#the-loop)
3. [Feedback Patterns](#feedback-patterns)
4. [Autonomous Loops](#autonomous-loops)
5. [Integration with Claude Code](#integration-with-claude-code)
6. [Anti-Patterns](#anti-patterns)
7. [See Also](#see-also)
---
## TL;DR
```
1. Initial prompt with clear goal
2. Claude produces output
3. Evaluate against criteria
4. Specific feedback: "Change X because Y"
5. Repeat until done
```
Key insight: **Specific feedback > vague feedback**
---
## The Loop
### Step 1: Initial Prompt
Start with clear intent and constraints:
```
Create a React component for a user profile card.
- Show avatar, name, bio
- Include edit button
- Use Tailwind CSS
- Mobile-responsive
```
### Step 2: Evaluate Output
Claude produces code. Evaluate:
- Does it meet requirements?
- What's missing?
- What's wrong?
- What could be better?
### Step 3: Specific Feedback
Provide targeted corrections:
```
Good start. Changes needed:
1. Avatar should be circular, not square
2. Edit button should only show for own profile (add isOwner prop)
3. Bio should truncate after 3 lines with "Show more"
```
### Step 4: Repeat
Continue until satisfied:
```
Better. One more thing:
- Add loading skeleton state for when data is fetching
```
---
## Feedback Patterns
### Effective Feedback
| Pattern | Example |
|---------|---------|
| **Specific location** | "Line 23: change `===` to `==`" |
| **Clear action** | "Add error boundary around the form" |
| **Reason given** | "Remove the console.log because it leaks user data" |
| **Priority marked** | "Critical: fix the SQL injection. Nice-to-have: add pagination." |
### Ineffective Feedback
| Anti-Pattern | Why It Fails | Better Alternative |
|--------------|--------------|-------------------|
| "Make it better" | No direction | "Improve readability by extracting the validation logic" |
| "This is wrong" | No specifics | "The date format should be ISO 8601, not Unix timestamp" |
| "I don't like it" | Subjective | "Use functional components instead of class components" |
| "Fix the bugs" | Too vague | "Fix: 1) null check on line 12, 2) off-by-one in loop" |
---
## Autonomous Loops
Claude can self-iterate with clear completion criteria.
### The Ralph Wiggum Pattern
Named after the self-improvement loop pattern:
```
Keep improving the code quality until:
1. All tests pass
2. No TypeScript errors
3. ESLint shows zero warnings
After each iteration, run the checks and fix any issues.
Stop when all criteria are met.
```
### Completion Criteria Examples
```
Iterate until:
- Response time < 100ms for 95th percentile
- Test coverage > 80%
- All accessibility checks pass
- Bundle size < 200KB
```
### Iteration Limits
Always set limits to prevent infinite loops:
```
Improve the algorithm performance.
Maximum 5 iterations.
Stop early if improvement < 5% between iterations.
```
---
## Integration with Claude Code
### With TodoWrite
Track refinement iterations:
```
TodoWrite:
- [x] Initial implementation
- [x] Fix: handle empty arrays
- [x] Fix: add input validation
- [ ] Optimization: memoize expensive calculations
```
### With Hooks
Auto-validate after each change:
```yaml
# .claude/hooks.yaml
post_edit:
- command: "npm run lint && npm test"
on_failure: "report"
```
Claude sees failures and can self-correct.
### With /compact
When context grows during iterations:
```
/compact
Continue refining the search algorithm.
We've made good progress, focus on the remaining issues.
```
### Checkpointing
After significant progress:
```
Good progress. Let's checkpoint:
- Commit what we have
- List remaining issues
- Continue with the next priority
```
---
## Iteration Strategies
### Breadth-First
Fix all issues at same level before going deeper:
```
First pass: Fix all type errors
Second pass: Fix all lint warnings
Third pass: Improve test coverage
Fourth pass: Optimize performance
```
### Depth-First
Complete one area fully before moving on:
```
1. Perfect the authentication flow (all aspects)
2. Then move to user management
3. Then move to settings
```
### Priority-Based
Address by importance:
```
Iterate in this order:
1. Security issues (critical)
2. Data integrity bugs (high)
3. UX problems (medium)
4. Code style (low)
```
---
## Anti-Patterns
### Moving Target
```
# Wrong
"Actually, let's change the approach entirely..."
(Repeated 5 times)
# Right
Commit to an approach, iterate within it.
If approach is wrong, explicitly restart.
```
### Perfectionism Loop
```
# Wrong
Keep improving forever
# Right
Set clear "good enough" criteria:
- Tests pass
- Handles main use cases
- No critical issues
→ Ship it, improve later
```
### Lost Context
```
# Wrong
After 50 iterations, forget what the goal was
# Right
Periodically restate the goal:
"Reminder: we're building a rate limiter.
Current state: basic implementation works.
Next: add Redis backend."
```
---
## Example Session
### Initial Request
```
Create a debounce function in TypeScript.
```
### Iteration 1
```
Looks good. Add:
- Generic type support for any function signature
- Option to execute on leading edge
```
### Iteration 2
```
Better. Issues:
- The return type should preserve the original function's return type
- Add cancellation support
```
### Iteration 3
```
Almost there. Final polish:
- Add JSDoc comments
- Export the types separately
- Add unit tests
```
### Completion
```
Perfect. Commit this as "feat: add debounce utility with full TypeScript support"
```
---
## See Also
- [tdd-with-claude.md](./tdd-with-claude.md) — TDD is iterative refinement with tests
- [plan-driven.md](./plan-driven.md) — Plan before iterating
- [../methodologies.md](../methodologies.md) — Iterative Loops methodology

View file

@ -0,0 +1,250 @@
# Plan-Driven Development
> **Confidence**: Tier 1 — Based on Claude Code's native /plan mode functionality.
Use `/plan` mode for anything non-trivial. Claude explores the codebase (read-only), then proposes an implementation plan for your approval.
---
## Table of Contents
1. [TL;DR](#tldr)
2. [The /plan Workflow](#the-plan-workflow)
3. [When to Use](#when-to-use)
4. [Plan File Structure](#plan-file-structure)
5. [Integration with Other Workflows](#integration-with-other-workflows)
6. [Tips](#tips)
7. [See Also](#see-also)
---
## TL;DR
```
1. /plan (or ask complex question)
2. Claude explores codebase (read-only)
3. Claude writes plan to .claude/plans/
4. You review and approve
5. Claude executes
```
---
## The /plan Workflow
### Step 1: Enter Plan Mode
Either use the slash command:
```
/plan
```
Or ask a complex question that triggers plan mode automatically:
```
How should I refactor the authentication system to support OAuth?
```
### Step 2: Claude Explores
In plan mode, Claude:
- Reads relevant files
- Searches for patterns
- Understands existing architecture
- CANNOT make any changes
### Step 3: Claude Writes Plan
Claude creates a plan file at `.claude/plans/[name].md`:
```markdown
# Plan: Refactor Authentication for OAuth
## Summary
Add OAuth support while maintaining existing email/password auth.
## Files to Modify
- src/auth/providers/index.ts (add OAuth provider)
- src/auth/middleware.ts (handle OAuth tokens)
- src/config/auth.ts (OAuth config)
## Files to Create
- src/auth/providers/oauth.ts
- src/auth/providers/google.ts
## Implementation Steps
1. Create OAuth provider interface
2. Implement Google OAuth provider
3. Update middleware to detect token type
4. Add OAuth routes
5. Update config schema
## Risks
- Breaking existing sessions during migration
- Token format differences between providers
```
### Step 4: You Review
Review the plan for:
- Completeness (all requirements covered)
- Correctness (right approach for your codebase)
- Scope (not over-engineering)
### Step 5: Approve and Execute
```
Looks good. Proceed with the plan.
```
Or request changes:
```
Modify the plan: also add support for GitHub OAuth, not just Google.
```
---
## When to Use
### Use Plan Mode
| Scenario | Why |
|----------|-----|
| Multi-file changes | See all affected files upfront |
| Architecture changes | Validate approach before coding |
| New features | Ensure complete implementation |
| Unfamiliar codebase | Let Claude explore first |
| Risky operations | Review before execution |
### Skip Plan Mode
| Scenario | Why |
|----------|-----|
| Single-line fixes | Obvious, low risk |
| Typo corrections | No planning needed |
| Simple questions | Exploration, not implementation |
| Adding comments | Trivial change |
---
## Plan File Structure
Plans are stored in `.claude/plans/` with auto-generated names.
### Typical Plan Sections
```markdown
# Plan: [Title]
## Summary
[1-2 sentence overview]
## Context
[Why this change is needed]
## Files to Modify
[List of existing files that will change]
## Files to Create
[List of new files]
## Files to Delete
[List of files to remove, if any]
## Implementation Steps
[Ordered list of steps]
## Testing Strategy
[How to verify the changes]
## Risks & Mitigations
[What could go wrong and how to handle it]
## Open Questions
[Things to clarify before proceeding]
```
---
## Integration with Other Workflows
### Plan + TDD
```
/plan
I need to implement a rate limiter.
Plan the test cases first, then the implementation.
```
Claude plans both tests and implementation in proper TDD order.
### Plan + Spec-First
```
/plan
Review the Payment Processing spec in CLAUDE.md.
Create an implementation plan that satisfies all acceptance criteria.
```
### Plan + TodoWrite
After plan approval, Claude can break down into todos:
```
Approved. Create a todo list from this plan and start implementing.
```
---
## Tips
### Be Specific About Scope
```
# Too vague
/plan
Improve the API
# Better
/plan
Add pagination to the /users endpoint with cursor-based navigation.
Maintain backwards compatibility with existing clients.
```
### Request Plan Modifications
```
The plan looks good but:
- Add error handling for network failures
- Skip the caching optimization for now
- Include rollback procedure
```
### Use for Architecture Decisions
```
/plan
I'm considering two approaches for state management:
A) Redux Toolkit
B) Zustand
Explore the codebase and recommend which fits better.
```
### Save Plans for Documentation
Plans in `.claude/plans/` serve as decision documentation:
- Why certain approaches were chosen
- What files were expected to change
- Implementation order rationale
---
## See Also
- [../ultimate-guide.md](../ultimate-guide.md) — Section 2.3 Plan Mode
- [tdd-with-claude.md](./tdd-with-claude.md) — Combine with TDD
- [spec-first.md](./spec-first.md) — Combine with Spec-First
- [iterative-refinement.md](./iterative-refinement.md) — Post-plan iteration

View file

@ -0,0 +1,326 @@
# Spec-First Development with Claude
> **Confidence**: Tier 2 — Validated by multiple production teams and aligns with official SDD guidance.
Define what you want in CLAUDE.md BEFORE asking Claude to build. One well-structured iteration equals 8 unstructured ones.
---
## Table of Contents
1. [TL;DR](#tldr)
2. [The Pattern](#the-pattern)
3. [CLAUDE.md Spec Templates](#claudemd-spec-templates)
4. [Step-by-Step Workflow](#step-by-step-workflow)
5. [Integration with Tools](#integration-with-tools)
6. [When to Use](#when-to-use)
7. [Anti-Patterns](#anti-patterns)
8. [See Also](#see-also)
---
## TL;DR
```
1. Write spec in CLAUDE.md
2. Claude reads spec automatically
3. Implementation follows spec exactly
4. Verify against spec
```
CLAUDE.md IS your spec file. Treat it as a contract.
---
## The Pattern
Spec-First Development inverts the typical AI coding flow:
```
Traditional: Spec-First:
─────────── ──────────
Prompt → Code Spec → Prompt → Code → Verify
│ │ │ │
└─ Hope it's └── Contract └── Follows spec
what you want defined └── Check against spec
```
The spec becomes the source of truth that:
- Constrains what Claude builds
- Documents decisions for the team
- Enables verification of completeness
---
## CLAUDE.md Spec Templates
### Feature Spec (Most Common)
```markdown
## Feature: [Name]
### Description
[2-3 sentences explaining the feature purpose]
### Capabilities
- MUST: [Required functionality]
- MUST: [Another requirement]
- SHOULD: [Nice to have]
- MUST NOT: [Explicit exclusions]
### Tech Stack
- Required: [lib1, lib2, lib3]
- Forbidden: [lib4, lib5]
### Acceptance Criteria
- [ ] Criterion 1: [Specific, testable condition]
- [ ] Criterion 2: [Another condition]
- [ ] Criterion 3: [Edge case handling]
### API Contract (if applicable)
- Endpoint: POST /api/[resource]
- Request: { field1: string, field2: number }
- Response: { id: string, created: timestamp }
- Errors: 400 (validation), 404 (not found), 500 (server)
```
### Architecture Spec
```markdown
## Architecture: [Component Name]
### Purpose
[Why this component exists]
### Boundaries
- Owns: [What this component is responsible for]
- Delegates to: [What other components handle]
- Does NOT: [Explicit non-responsibilities]
### Dependencies
- Upstream: [Components that call this]
- Downstream: [Components this calls]
### Data Flow
```
Input → Validation → Processing → Output
│ │
└─ Errors ─────┘
```
### Constraints
- Performance: [Response time, throughput]
- Security: [Auth requirements, data handling]
- Scalability: [Expected load, limits]
```
### API Spec
```markdown
## API: [Endpoint Name]
### Endpoint
`POST /api/v1/[resource]`
### Authentication
Bearer token required. Scopes: `read:resource`, `write:resource`
### Request
```json
{
"field1": "string (required, max 255 chars)",
"field2": "number (optional, default: 0)",
"nested": {
"subfield": "boolean"
}
}
```
### Response
```json
{
"id": "uuid",
"created_at": "ISO 8601 timestamp",
"data": { ... }
}
```
### Error Codes
| Code | Meaning | Response Body |
|------|---------|---------------|
| 400 | Validation failed | `{ "errors": [...] }` |
| 401 | Not authenticated | `{ "message": "..." }` |
| 403 | Not authorized | `{ "message": "..." }` |
| 404 | Resource not found | `{ "message": "..." }` |
```
---
## Step-by-Step Workflow
### Step 1: Write the Spec
Before any implementation request, add spec to CLAUDE.md:
```markdown
## Feature: User Authentication
### Capabilities
- MUST: Email/password login
- MUST: JWT token generation
- MUST: Password hashing with bcrypt
- SHOULD: Remember me functionality
- MUST NOT: Store plain text passwords
### Tech Stack
- Required: bcrypt, jsonwebtoken
- Forbidden: passport.js (too heavy for this use case)
### Acceptance Criteria
- [ ] User can login with valid credentials
- [ ] Invalid credentials return 401
- [ ] Token expires after 24h (or 7d with remember me)
- [ ] Passwords hashed with cost factor 12
```
### Step 2: Reference Spec in Prompt
```
Implement the User Authentication feature as specified in CLAUDE.md.
Follow the acceptance criteria exactly.
```
Claude automatically reads CLAUDE.md and follows the spec.
### Step 3: Verify Against Spec
After implementation, verify:
```
Review the implementation against the User Authentication spec.
Check off each acceptance criterion that's satisfied.
List any gaps.
```
### Step 4: Update Spec if Needed
If requirements change during implementation:
```
Update the User Authentication spec to include:
- MUST: Rate limiting (5 attempts per minute)
Then implement the rate limiting.
```
---
## Integration with Tools
### With Spec Kit (Greenfield)
```bash
# Install Spec Kit
npx @anthropic/spec-kit init
# Use slash commands
/speckit.constitution # Define project guardrails
/speckit.specify # Write feature specs
/speckit.plan # Create implementation plan
/speckit.implement # Build from spec
```
### With OpenSpec (Brownfield)
```bash
# Install OpenSpec
npm install -g @fission-ai/openspec@latest
openspec init
# Use slash commands
/openspec:proposal "Add dark mode" # Create change proposal
/openspec:apply add-dark-mode # Implement changes
/openspec:archive add-dark-mode # Merge to specs
```
### With /plan Mode
```
/plan
I need to implement the Payment Processing feature.
Review the spec in CLAUDE.md and create an implementation plan.
```
---
## When to Use
### Use Spec-First
| Scenario | Why |
|----------|-----|
| New features | Define before building |
| API design | Contract must be explicit |
| Architecture decisions | Document constraints |
| Team collaboration | Shared understanding |
| Complex requirements | Reduce ambiguity |
### Skip Spec-First
| Scenario | Why |
|----------|-----|
| Quick fixes | Overhead not worth it |
| Exploration | Don't know what you want yet |
| Prototyping | Requirements will change |
| Single-line changes | Obvious intent |
---
## Anti-Patterns
### Vague Specs
```markdown
# Wrong
## Feature: User Management
- Handle users
# Right
## Feature: User Management
### Capabilities
- MUST: Create user with email, password, name
- MUST: Update user profile (name, avatar)
- MUST: Soft delete (mark as inactive, don't remove data)
- MUST NOT: Allow duplicate emails
```
### Spec After Code
```
# Wrong workflow
1. Ask Claude to implement feature
2. Write spec documenting what was built
# Right workflow
1. Write spec defining what should be built
2. Ask Claude to implement from spec
```
### Ignoring Forbidden
```markdown
# Don't forget exclusions
### Tech Stack
- Required: React, TypeScript
- Forbidden: jQuery, vanilla JS, class components
↑ These constraints prevent drift
```
---
## See Also
- [../methodologies.md](../methodologies.md) — SDD and other methodologies
- [Spec Kit Documentation](https://github.blog/ai-and-ml/generative-ai/spec-driven-development-with-ai-get-started-with-a-new-open-source-toolkit/)
- [OpenSpec Documentation](https://github.com/Fission-AI/OpenSpec)
- [tdd-with-claude.md](./tdd-with-claude.md) — Combine with TDD

View file

@ -0,0 +1,304 @@
# TDD with Claude Code
> **Confidence**: Tier 1 — Based on official Anthropic best practices and extensive community validation.
Test-Driven Development with Claude requires explicit prompting. Claude naturally writes implementation first, then tests. TDD requires the inverse.
---
## Table of Contents
1. [TL;DR](#tldr)
2. [The Problem](#the-problem)
3. [Setup](#setup)
4. [The Red-Green-Refactor Cycle](#the-red-green-refactor-cycle)
5. [Integration with Claude Code Features](#integration-with-claude-code-features)
6. [Anti-Patterns](#anti-patterns)
7. [Advanced Patterns](#advanced-patterns)
8. [See Also](#see-also)
---
## TL;DR
```
Red → Green → Refactor
But you MUST prompt Claude explicitly:
"Write a FAILING test for [feature]. Do NOT write implementation yet."
```
---
## The Problem
Without explicit instruction, Claude will:
1. Write implementation code
2. Then write tests that pass against that implementation
This defeats TDD's purpose: tests should drive design, not validate existing code.
---
## Setup
### CLAUDE.md Configuration
Add to your project's CLAUDE.md:
```markdown
## Testing Conventions
### TDD Workflow
- Always write failing tests BEFORE implementation
- Use AAA pattern: Arrange-Act-Assert
- One assertion per test when possible
- Test names describe behavior: "should_return_empty_when_no_items"
### Test-First Rules
- When I ask for a feature, write tests first
- Tests should FAIL initially (no implementation exists)
- Only after tests are written, implement minimal code to pass
```
### Hook for Auto-Run Tests (Optional)
Create `.claude/hooks/test-on-save.sh`:
```bash
#!/bin/bash
# Auto-run tests when test files change
if [[ "$1" == *test* ]] || [[ "$1" == *spec* ]]; then
npm test --watchAll=false 2>&1 | head -20
fi
```
---
## The Red-Green-Refactor Cycle
### Phase 1: Red (Write Failing Test)
**Prompt**:
```
Write a failing test for [feature description].
Do NOT write the implementation yet.
The test should fail because the function/method doesn't exist.
```
**Example**:
```
Write a failing test for a function that calculates the total price
of items in a cart, applying a 10% discount if total exceeds $100.
Do NOT implement the function yet.
```
**Expected Claude behavior**:
- Creates test file with test cases
- Tests reference function that doesn't exist
- Running tests would fail with "function not defined" or similar
**Verification**:
```bash
npm test # Should fail with "calculateCartTotal is not defined"
```
### Phase 2: Green (Minimal Implementation)
**Prompt**:
```
Now implement the minimum code to make these tests pass.
Only write enough code to pass the current tests, nothing more.
```
**Expected Claude behavior**:
- Creates implementation file
- Writes minimal code to satisfy tests
- Avoids over-engineering
**Verification**:
```bash
npm test # Should pass
```
### Phase 3: Refactor (Clean Up)
**Prompt**:
```
Refactor the implementation to improve code quality.
Tests must stay green after refactoring.
Focus on: [readability / performance / removing duplication]
```
**Expected Claude behavior**:
- Improves code without changing behavior
- Runs tests to verify they still pass
- Documents any significant changes
---
## Integration with Claude Code Features
### With TodoWrite
Track TDD phases in your task list:
```
User: "Implement user authentication with TDD"
Claude creates todos:
- [ ] RED: Write failing tests for login
- [ ] GREEN: Implement login to pass tests
- [ ] REFACTOR: Clean up login implementation
- [ ] RED: Write failing tests for logout
- [ ] GREEN: Implement logout
- [ ] REFACTOR: Clean up
```
### With /plan Mode
Use planning for test strategy:
```
/plan
I need to implement a shopping cart with TDD.
Plan the test cases before we start writing any code.
```
Claude will explore codebase, then propose test plan before any implementation.
### With Hooks
Auto-run tests on file changes:
```yaml
# .claude/hooks.yaml
post_edit:
- pattern: "**/*.test.ts"
command: "npm test -- --testPathPattern=$FILE"
- pattern: "**/*.ts"
command: "npm test --watchAll=false"
```
### With Sub-Agents
Delegate test writing to specialized agent:
```
Use the test-writer agent to create comprehensive tests for
the UserService class, covering all edge cases.
Then I'll implement to pass those tests.
```
---
## Anti-Patterns
### What NOT to do
| Anti-Pattern | Why It's Wrong | Correct Approach |
|--------------|----------------|------------------|
| "Write tests for this feature" | Claude implements first | "Write FAILING tests that don't exist yet" |
| "Add tests and implementation" | Loses test-first benefit | Separate into two prompts |
| "Make sure tests pass" | Encourages implementation-first | "Write tests, then implement minimally" |
| Skipping refactor phase | Accumulates technical debt | Always refactor after green |
| Multiple features at once | Loses focus | One feature per TDD cycle |
### Common Mistakes
**Mistake**: Asking Claude to "test" existing code.
```
# Wrong
"Write tests for the existing calculateTotal function"
# Right
"Write tests for calculateTotal behavior, assuming function doesn't exist.
Then we'll verify the existing implementation passes."
```
**Mistake**: Combining red and green phases.
```
# Wrong
"Implement calculateTotal with tests"
# Right
"Write failing tests for calculateTotal. Stop there."
[After tests written]
"Now implement to pass those tests."
```
---
## Advanced Patterns
### Property-Based Testing
```
Write property-based tests for the sort function.
Properties to test:
- Output length equals input length
- All input elements exist in output
- Output is ordered
Use fast-check or similar library.
```
### Mutation Testing
```
After tests pass, run mutation testing to find weak spots.
Identify tests that don't catch mutations.
```
### TDD with Legacy Code
```
I need to refactor legacyFunction.
First, write characterization tests that capture current behavior.
Then we'll refactor with confidence.
```
---
## Example Session
### User Request
```
Implement a URL shortener service with TDD.
```
### Phase 1: Red
```
Let's use TDD. First, write failing tests for:
1. Shortening a URL returns a short code
2. Retrieving a short code returns original URL
3. Invalid URLs are rejected
4. Expired links return error
Do NOT implement anything yet.
```
### Phase 2: Green
```
Tests are written and failing. Now implement the minimum
code to make them pass. Use an in-memory store for now.
```
### Phase 3: Refactor
```
Tests pass. Now refactor:
- Extract URL validation to separate function
- Add proper error types
- Improve variable names
Run tests after each change to ensure they stay green.
```
---
## See Also
- [../methodologies.md](../methodologies.md) — Full methodology reference
- [Tight Feedback Loops](../ultimate-guide.md) — Section 9.5
- [examples/skills/tdd-workflow.md](../../examples/skills/tdd-workflow.md) — TDD skill template
- [Anthropic Best Practices](https://www.anthropic.com/engineering/claude-code-best-practices)