# Playbook: Updating Documentation

**Goal:** Ensure all code changes include complete, accurate documentation
**Audience:** Developers and AI assistants
**Time:** 5-15 minutes per change (integrated with coding)

---

## When to Use This Playbook

Use this playbook whenever you:
- Add a new feature or function
- Fix a bug that changes behavior
- Refactor code in a way that affects usage
- Change an API or interface
- Update configuration options
- Make any user-facing changes

---

## Quick Start (TL;DR)

```bash
# 1. Before coding: Read existing docs
Read README.md docs/

# 2. While coding: Add docstrings immediately
# Write docstrings as you create functions

# 3. After coding: Update external docs
Edit README.md docs/api.md  # Update relevant docs

# 4. Before commit: Verify completeness
# Check PR template documentation checklist

# 5. Commit together
git add src/ docs/ README.md
git commit -m "feat: description

- Code changes
- Documentation updates

Co-Authored-By: Name <email>"
```

---

## Detailed Workflow

### Step 1: Assess Documentation Needs

**Before writing any code**, determine what documentation will be affected:

```bash
# Question checklist:
# [ ] Is this user-facing? → Update README
# [ ] Does it change an API? → Update API docs
# [ ] Is it a new pattern? → Update architecture docs
# [ ] Is it complex logic? → Add inline comments
# [ ] Is it a new function? → Add docstring (always required)
# [ ] Is it a bug fix? → Update docs if behavior changes
```

**Read existing documentation:**

```bash
# Read relevant docs to understand current state
cat README.md
cat docs/api.md
cat docs/architecture.md

# Search for references to what you're changing
grep -r "function_name" docs/
grep -r "feature_name" README.md
```

### Step 2: Write Code with Inline Documentation

**As you write each function, add the docstring immediately:**

```python
# ✅ GOOD: Docstring added while writing function
def validate_user_input(
    user_id: str,
    data: dict[str, Any],
    strict: bool = False
) -> ValidationResult:
    """Validate user input against schema and business rules.

    Args:
        user_id: Unique identifier for the user
        data: Input data to validate
        strict: If True, treat warnings as errors

    Returns:
        ValidationResult with status, errors, and warnings

    Raises:
        UserNotFoundError: If user_id doesn't exist
        SchemaError: If data doesn't match expected schema
        ValidationError: If strict=True and warnings present

    Example:
        >>> result = validate_user_input("user123", {"name": "Alice"})
        >>> if result.is_valid:
        ...     print("Valid input!")
    """
    # Complex logic gets explanatory comments
    # Validate against schema first (fast check)
    schema_result = validate_schema(data)
    if not schema_result.is_valid:
        return ValidationResult(valid=False, errors=schema_result.errors)

    # Then validate business rules (slower, DB queries)
    # Only run if schema validation passed
    business_result = validate_business_rules(user_id, data)

    return ValidationResult.combine(schema_result, business_result)
```

**Add comments for complex logic:**

```python
# ✅ GOOD: Explains WHY, not just WHAT
# Use binary search instead of linear scan for performance
# Assumes data is sorted by timestamp (enforced in loader)
index = bisect_left(sorted_data, target_value)

# Cache results to avoid repeated DB queries
# Cache TTL is 5 minutes to balance freshness and performance
@cache(ttl=300)
def get_user_preferences(user_id: str) -> dict:
    ...
```

### Step 3: Update External Documentation

**After writing code, update external docs before committing:**

#### README.md Updates

Update README if changes are user-facing:

```markdown
<!-- Add new section or update existing section -->

## Authentication

### Setup

1. Install authentication package:
   ```bash
   pip install myproject[auth]
   ```

2. Configure authentication:
   ```python
   from myproject.auth import JWTAuth

   auth = JWTAuth(
       secret_key="your-secret-key",
       token_expiry=3600  # 1 hour
   )
   ```

3. Use authentication:
   ```python
   # Login to get token
   token = auth.login(username="alice", password="secret")

   # Use token for protected requests
   result = api.get_user_data(token=token)
   ```

### Troubleshooting

**Token expired error:**
- Tokens expire after 1 hour
- Use refresh token to get new access token
- See [API docs](docs/api.md#token-refresh) for details
```

#### API Documentation Updates

Update API docs if endpoints or interfaces changed:

```markdown
<!-- docs/api.md -->

## Authentication Endpoints

### POST /auth/login

Authenticate user and receive JWT token.

**Request:**
```json
{
  "username": "alice",
  "password": "secret123"
}
```

**Response (200 OK):**
```json
{
  "access_token": "eyJhbGc...",
  "refresh_token": "eyJhbGc...",
  "expires_in": 3600
}
```

**Error Responses:**

| Status | Error | Description |
|--------|-------|-------------|
| 401 | `invalid_credentials` | Username or password incorrect |
| 429 | `rate_limited` | Too many login attempts |

**Example:**
```python
import requests

response = requests.post(
    "https://api.example.com/auth/login",
    json={"username": "alice", "password": "secret123"}
)

if response.status_code == 200:
    token = response.json()["access_token"]
    print(f"Logged in! Token: {token}")
else:
    print(f"Login failed: {response.json()['error']}")
```
```

#### Architecture Documentation Updates

Update architecture docs if patterns or design changed:

```markdown
<!-- docs/architecture.md -->

## Authentication System

### Overview

JWT-based stateless authentication with token refresh mechanism.

### Components

```
┌─────────────┐
│   Client    │
└──────┬──────┘
       │
       │ 1. POST /auth/login
       ↓
┌─────────────────────────────────────┐
│     Authentication Service          │
│  ┌──────────────────────────────┐  │
│  │ 1. Validate credentials      │  │
│  │ 2. Generate JWT tokens       │  │
│  │ 3. Return tokens to client   │  │
│  └──────────────────────────────┘  │
└─────────────────────────────────────┘
       │
       │ 2. Token response
       ↓
┌─────────────┐
│   Client    │ (stores tokens)
└─────────────┘
```

### Design Decisions

**Why JWT instead of sessions?**
- Stateless: No server-side session storage needed
- Scalable: Works across multiple servers without shared state
- Standard: Well-supported by libraries and tools

**Why 1-hour token expiry?**
- Balance between security and user experience
- Short enough to limit damage if token stolen
- Long enough to avoid constant re-authentication
- Refresh tokens provide longer session duration

### Security Considerations

- Passwords hashed with bcrypt (12 rounds)
- Tokens signed with HS256 algorithm
- Refresh tokens stored securely (HTTP-only cookies in web app)
- Rate limiting on login endpoint (5 attempts per minute)
```

### Step 4: Verify Documentation Completeness

**Before committing, check the documentation:**

```bash
# Checklist:
# [ ] All new functions have docstrings
# [ ] Complex logic has explanatory comments
# [ ] README updated (if user-facing change)
# [ ] API docs updated (if API changed)
# [ ] Architecture docs updated (if design changed)
# [ ] CHANGELOG updated (if versioned release)
# [ ] Examples still work and are up-to-date
# [ ] No "TODO: Add docs" comments left behind
```

**Test documentation examples:**

```bash
# If you included code examples, test them:
python -c "from myproject.auth import JWTAuth; auth = JWTAuth('secret')"

# Verify examples in docstrings work:
python -m doctest src/myproject/auth.py -v
```

### Step 5: Commit Code and Docs Together

**Commit code and documentation in the same commit:**

```bash
# Stage both code and documentation changes
git add src/myproject/auth.py
git add docs/api.md
git add README.md

# Commit with descriptive message
git commit -m "feat: add JWT authentication

- Implement JWTAuth class with login/refresh methods
- Add /auth/login and /auth/refresh endpoints
- Update API documentation with authentication examples
- Add authentication setup section to README
- Add architecture docs explaining JWT design decisions

Co-Authored-By: Name <email@example.com>"
```

**Why commit together?**
- Ensures docs and code stay in sync
- Easier to review (reviewer sees full context)
- Easier to revert (one commit contains everything)
- Prevents "I'll document it later" syndrome

### Step 6: Complete PR Documentation Checklist

**When creating PR, complete the documentation checklist:**

```markdown
## Documentation Checklist

- [x] Code changes have corresponding doc updates
- [x] README updated (added authentication section)
- [x] API docs updated (documented /auth endpoints)
- [x] Architecture docs updated (explained JWT design)
- [x] Docstrings added (all JWTAuth methods documented)
- [x] Comments added (explained token validation logic)
- [ ] No documentation needed
```

---

## Common Scenarios

### Scenario 1: Adding a New Feature

**Example:** Adding user profile feature

```bash
# 1. Assess what docs are needed
# - User-facing → Update README
# - New API endpoints → Update API docs
# - New pattern → Update architecture docs

# 2. Write code with docstrings
Edit src/profiles.py  # Add UserProfile class with docstrings

# 3. Update external docs
Edit README.md        # Add "User Profiles" section
Edit docs/api.md      # Document /profiles endpoints
Edit docs/architecture.md  # Explain profile storage design

# 4. Commit together
git add src/profiles.py README.md docs/
git commit -m "feat: add user profile management

- Add UserProfile model with CRUD operations
- Add /profiles endpoints for profile management
- Update README with profile usage guide
- Document profile API endpoints
- Explain profile storage in architecture docs"
```

### Scenario 2: Fixing a Bug

**Example:** Fixing memory leak

```bash
# 1. Assess documentation needs
# - Behavior changed? → Update docstring
# - User-visible? → Update README
# - Complex fix? → Add comments

# 2. Fix bug and update docstring
Edit src/processor.py
# Update docstring to clarify memory management
# Add comment explaining fix

# 3. Update README if user-visible
# If memory leak caused crashes, mention fix in README

# 4. Commit
git commit -m "fix: resolve memory leak in data processor

Fixed leak caused by circular references in DataProcessor.
Added explicit cleanup in __del__ method.

Updated docstring to document cleanup behavior.
Added comment explaining reference cycle breaking."
```

### Scenario 3: Refactoring Code

**Example:** Splitting large module into smaller modules

```bash
# 1. Assess documentation needs
# - API changed? → Update docs showing new imports
# - Architecture changed? → Update architecture docs
# - Examples affected? → Update examples

# 2. Refactor code, update docstrings
Edit src/validators/  # Split into submodules
# Update docstrings with new import paths

# 3. Update documentation
Edit README.md  # Update import examples
Edit docs/architecture.md  # Explain new module structure
Edit examples/  # Update examples with new imports

# 4. Commit
git commit -m "refactor: split validators into submodules

Split large validators.py (600 lines) into focused submodules:
- validators/schema.py - Schema validation
- validators/business.py - Business rule validation
- validators/base.py - Base classes

Updated all imports and examples.
Updated architecture docs with new module structure."
```

### Scenario 4: Documentation-Only Changes

**Example:** Improving unclear documentation

```bash
# 1. Improve documentation
Edit README.md  # Clarify setup instructions
Edit docs/api.md  # Add missing examples
Edit docs/troubleshooting.md  # Add FAQ section

# 2. Commit with docs: prefix
git commit -m "docs: improve authentication documentation

- Add step-by-step setup guide with examples
- Add code examples for all auth endpoints
- Add troubleshooting section for common issues
- Fix typos in API documentation

Based on user feedback in issue #123."
```

---

## Documentation Templates

### Docstring Template (Google Style)

```python
def function_name(
    param1: Type1,
    param2: Type2,
    param3: Type3 = default_value
) -> ReturnType:
    """One-line summary of what function does.

    More detailed explanation if needed. Explain any important
    behavior, assumptions, or constraints.

    Args:
        param1: Description of first parameter
        param2: Description of second parameter
        param3: Description of optional parameter with default

    Returns:
        Description of return value. For complex returns, describe
        the structure or important fields.

    Raises:
        ErrorType1: When this error occurs
        ErrorType2: When this error occurs

    Example:
        >>> result = function_name(value1, value2)
        >>> print(result)
        expected_output

    Note:
        Any additional notes, warnings, or important information.
        For example, performance characteristics, thread-safety, etc.
    """
    ...
```

### README Section Template

```markdown
## Feature Name

Brief description of the feature and what problem it solves.

### Installation

If feature requires additional dependencies:

```bash
pip install myproject[feature-name]
```

### Quick Start

Minimal example showing basic usage:

```python
from myproject.feature import FeatureClass

# Basic usage
feature = FeatureClass()
result = feature.do_something()
print(result)
```

### Configuration

Describe available configuration options:

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `option1` | `str` | `"default"` | What this option controls |
| `option2` | `int` | `10` | What this option controls |

### Examples

**Example 1: Common use case**
```python
# Code example with explanatory comments
result = feature.do_something(option1="value")
```

**Example 2: Advanced use case**
```python
# More complex example
result = feature.advanced_usage(
    option1="value",
    option2=20
)
```

### Troubleshooting

**Error: common error message**
- Cause: Why this error occurs
- Solution: How to fix it

### See Also

- [API Documentation](docs/api.md#feature-name)
- [Architecture Details](docs/architecture.md#feature-design)
```

### API Documentation Template

```markdown
## Endpoint Name

### `METHOD /path/to/endpoint`

Brief description of what endpoint does.

**Authentication:** Required/Optional/Not required

**Request Parameters:**

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `param1` | `string` | Yes | Description |
| `param2` | `integer` | No | Description (default: 10) |

**Request Body:**
```json
{
  "field1": "value",
  "field2": 123
}
```

**Response (200 OK):**
```json
{
  "result": "success",
  "data": { ... }
}
```

**Error Responses:**

| Status | Error Code | Description |
|--------|------------|-------------|
| 400 | `invalid_params` | Parameter validation failed |
| 401 | `unauthorized` | Authentication required |
| 404 | `not_found` | Resource not found |

**Example Request:**
```python
import requests

response = requests.get(
    "https://api.example.com/path/to/endpoint",
    params={"param1": "value"},
    headers={"Authorization": f"Bearer {token}"}
)

if response.status_code == 200:
    data = response.json()
    print(f"Success: {data}")
```

**Rate Limiting:** X requests per minute

**See Also:**
- [Related Endpoint](#related-endpoint)
```

---

## Tips for Writing Good Documentation

### For Docstrings

- Start with one-line summary (imperative mood: "Calculate", not "Calculates")
- Describe parameters clearly (not just type, but meaning and constraints)
- Document exceptions (when they're raised, not just what they are)
- Include examples for complex functions
- Keep it concise but complete

### For README

- Write for users, not developers (explain benefits, not implementation)
- Start with quick start (minimal viable example)
- Provide troubleshooting for common issues
- Use screenshots/diagrams for visual features
- Keep examples up-to-date

### For API Docs

- Document every endpoint completely
- Include real request/response examples
- Document all error cases
- Show code examples in user's language
- Note rate limits and auth requirements

### For Architecture Docs

- Explain WHY decisions were made (not just WHAT)
- Include diagrams for complex systems
- Document trade-offs considered
- Keep updated as system evolves
- Link to relevant code

---

## Common Documentation Mistakes

### Mistake 1: "I'll document it later"

❌ **Wrong:**
```python
# TODO: Add documentation
def complex_function(data):
    # Complex logic without explanation
    ...
```

✅ **Right:**
```python
def complex_function(data: pd.DataFrame) -> ProcessedData:
    """Process complex data transformation.

    Args:
        data: Input dataframe with required columns

    Returns:
        ProcessedData with transformation results
    """
    # Document as you write
    ...
```

### Mistake 2: Outdated documentation

❌ **Wrong:**
```python
# Function signature changed but docstring didn't
def process(data: dict, schema: Schema, strict: bool = False):
    """Process data.

    Args:
        data: Input data
        # Missing: schema and strict parameters!

    Returns:
        Result
    """
    ...
```

✅ **Right:**
Update docstring when changing function signature.

### Mistake 3: Obvious comments

❌ **Wrong:**
```python
# Increment counter by 1
counter += 1

# Loop through items
for item in items:
    ...
```

✅ **Right:**
Only comment non-obvious logic:
```python
# Use counter to track retry attempts for exponential backoff
counter += 1
delay = 2 ** counter  # 2, 4, 8, 16, 32 seconds
```

### Mistake 4: Separate documentation commits

❌ **Wrong:**
```bash
git commit -m "feat: add feature"
# ... later ...
git commit -m "docs: document feature"  # Separate!
```

✅ **Right:**
```bash
git add src/ docs/ README.md
git commit -m "feat: add feature

- Implementation
- Documentation updates"
```

---

## Checklist for Complete Documentation

Before submitting PR:

### Code Documentation
- [ ] All functions have docstrings
- [ ] Docstrings include Args, Returns, Raises sections
- [ ] Complex logic has explanatory comments
- [ ] Comments explain WHY, not WHAT
- [ ] No "TODO: Add docs" comments remain

### External Documentation
- [ ] README updated (if user-facing changes)
- [ ] API docs updated (if API/endpoints changed)
- [ ] Architecture docs updated (if design changed)
- [ ] CHANGELOG updated (if versioned release)
- [ ] Examples updated and tested

### PR Documentation
- [ ] PR title uses semantic prefix
- [ ] PR description explains what and why
- [ ] Documentation checklist completed in PR template
- [ ] Breaking changes documented (if any)
- [ ] Screenshots included (for UI changes)

### Quality
- [ ] Documentation is accurate (matches code)
- [ ] Documentation is clear (easy to understand)
- [ ] Examples actually work (tested them)
- [ ] No typos or formatting issues

---

## Related Documentation

- **Knowledge Base**: `.claude/knowledge/documentation/keeping-docs-updated.md`
- **Critical Rules**: `.claude/standards/CLAUDE_CODE_RULES.md` (Rule #11)
- **Engineering Standards**: `.claude/standards/ENGINEERING_STANDARDS.md`
- **PR Titles**: `.claude/knowledge/git/pr-titles-and-descriptions.md`

---

**Status**: Playbook for systematic documentation updates. Updated: 2026-01-07
