agentleFS
StormixStormix/transcripts-mcp/.cursor/rules/070-comments-defensive-programming.mdc

transcripts-mcp / rules

Cursor rule8 starsChanged 2 months agoMITView on GitHub

Comments and Defensive Programming Guidelines - Minimize unnecessary comments and defensive code

The file

We split this 070-comments-defensive-programming.mdc into the rules it gives an agent

11 rules. About 0 are common, 11 are distinctive, and 0 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈11

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 0

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Write code that is self-documenting and robust by design, not through excessive commenting or defensive programming.

    line 10
  2. Distinctive:

    ✅ Business Logic Context: - When the code implements complex business rules:

    line 60
  3. Distinctive:

    ✅ Non-Obvious Algorithms: - When using specific algorithms or optimizations:

    line 68
  4. Distinctive:

    ✅ AI Context Hints: - When you need to leave hints for future AI assistance:

    line 78
  5. Distinctive:

    ✅ External API Boundaries: - When dealing with external data:

    line 150
  6. Distinctive:

    ✅ User Input Validation: - When handling user-provided data:

    line 160
  7. Distinctive:

    ✅ Critical System Operations: - When failure would be catastrophic:

    line 174
  8. Distinctive:

    Write self-documenting code: - Use clear variable names, small functions, and logical structure

    line 243
  9. Distinctive:

    Trust your type system: - Use TypeScript effectively instead of runtime checks

    line 244
  10. Distinctive:

    Validate at boundaries: - Check external data, but trust internal data flow

    line 246
  11. Distinctive:

    When reviewing code, ask:

    line 251

≈ “Common” is an estimate: at least 1 in 5 of the 6,668 Cursor rule files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
070-comments-defensive-programming.mdc
---
description: Comments and Defensive Programming Guidelines - Minimize unnecessary comments and defensive code
alwaysApply: true
---

# Comments and Defensive Programming Guidelines

## Philosophy

Write code that is self-documenting and robust by design, not through excessive commenting or defensive programming. Code should be clear enough to understand without explanatory comments, and defensive programming should only be used when genuinely necessary.

## Comments Policy

### Avoid These Types of Comments

**❌ Obvious Comments** - Comments that simply repeat what the code does:

```typescript
// Bad: Comment just repeats the code
// Create a new user
const user = new User();

// Bad: Obvious variable assignment
// Set the user's name to John
user.name = "John";

// Bad: Obvious function call
// Call the save method
await user.save();
```

**❌ Redundant Implementation Comments**:

```typescript
// Bad: Implementation is clear from the code
// Loop through all users
for (const user of users) {
  // Check if user is active
  if (user.isActive) {
    // Add to active users array
    activeUsers.push(user);
  }
}
```

**❌ Empty Defensive Comments**:

```typescript
// Bad: Generic error handling comment
try {
  await processData();
} catch (error) {
  // Handle error
  throw error;
}
```

### When Comments ARE Appropriate

**✅ Business Logic Context** - When the code implements complex business rules:

```typescript
// Apply company-specific tax calculation:
// Base rate + regional modifier + seasonal adjustment
const taxRate = baseTaxRate * (1 + regionalModifier) + seasonalAdjustment;
```

**✅ Non-Obvious Algorithms** - When using specific algorithms or optimizations:

```typescript
// Using Floyd-Warshall algorithm for shortest path calculation
// because we need all-pairs shortest paths, not single-source
for (let k = 0; k < vertices; k++) {
  // implementation...
}
```

**✅ AI Context Hints** - When you need to leave hints for future AI assistance:

```typescript
// TODO: This validation logic will need to be updated when we migrate
// to the new authentication system in Q2 2024
function validateUserToken(token: string) {
  // Current implementation uses JWT, future will use OAuth2
  return jwt.verify(token, secret);
}
```

**✅ API/Interface Documentation** - For public APIs and complex interfaces:

```typescript
/**
 * Processes mod files with specific validation requirements
 * @param files - Array of mod files to process
 * @param options - Processing options including validation level
 * @returns Promise resolving to processed mod metadata
 */
export async function processModFiles(
  files: ModFile[],
  options: ProcessingOptions
): Promise<ModMetadata[]> {
  // implementation...
}
```

## Defensive Programming Guidelines

### Avoid Unnecessary Defensive Code

**❌ Over-validation of Internal APIs**:

```typescript
// Bad: Excessive validation for internal function
function calculateTotal(items: Item[]) {
  if (!items) throw new Error("Items cannot be null");
  if (!Array.isArray(items)) throw new Error("Items must be an array");
  if (items.length === 0) throw new Error("Items cannot be empty");

  // The actual logic...
}
```

**❌ Catching and Re-throwing Without Value**:

```typescript
// Bad: Pointless error wrapping
try {
  await database.save(user);
} catch (error) {
  // Just re-throwing doesn't add value
  throw new Error(`Failed to save user: ${error.message}`);
}
```

**❌ Excessive Null Checks for Known Data**:

```typescript
// Bad: User is guaranteed to exist at this point
function updateUserProfile(user: User) {
  if (!user) throw new Error("User is required");
  if (!user.id) throw new Error("User ID is required");
  if (!user.profile) throw new Error("User profile is required");

  // Update logic...
}
```

### When Defensive Programming IS Appropriate

**✅ External API Boundaries** - When dealing with external data:

```typescript
// Good: External API data needs validation
function processExternalUserData(apiData: string) {
  const userData = UserSchema.parse(JSON.parse(apiData));
  return createUser(userData);
}
```

**✅ User Input Validation** - When handling user-provided data:

```typescript
// Good: User input should always be validated
function validateModFile(file: File) {
  if (file.size > MAX_FILE_SIZE) {
    throw new ValidationError("File too large");
  }
  if (!ALLOWED_EXTENSIONS.includes(file.extension)) {
    throw new ValidationError("Invalid file type");
  }
}
```

**✅ Critical System Operations** - When failure would be catastrophic:

```typescript
// Good: Critical operations need safety checks
async function deleteUserData(userId: string) {
  if (!userId || userId.length < 10) {
    throw new Error("Invalid user ID for deletion");
  }

  // Additional safety: Verify user exists and is marked for deletion
  const user = await getUserById(userId);
  if (!user.markedForDeletion) {
    throw new Error("User not marked for deletion");
  }

  await database.deleteUser(userId);
}
```

## Error Handling Philosophy

### Let It Break When Appropriate

**It's OK to let the application break when:**

- The error indicates a programming mistake that should be fixed
- The failure is due to incorrect internal API usage
- The error would help identify bugs during development
- Defensive code would hide underlying issues

**Example - Let it crash:**

```typescript
// Good: Let TypeScript and runtime catch programming errors
function processUserArray(users: User[]) {
  return users.map((user) => ({
    id: user.id, // Will fail if user is null - this is good!
    name: user.name, // Will fail if user lacks name - catch the bug!
    email: user.email.toLowerCase(), // Will fail if email is undefined - fix the source!
  }));
}
```

### Handle Errors That Matter

**Handle errors when:**

- They represent expected business conditions
- They come from external systems
- They affect user experience
- Recovery is possible and meaningful

**Example - Handle gracefully:**

```typescript
// Good: Handle external API failures gracefully
async function fetchUserAvatar(userId: string): Promise<string | null> {
  try {
    const response = await fetch(`/api/avatars/${userId}`);
    if (!response.ok) return null;
    return await response.text();
  } catch {
    return null; // Graceful degradation for avatar loading
  }
}
```

## Implementation Guidelines

1. **Write self-documenting code** - Use clear variable names, small functions, and logical structure
2. **Trust your type system** - Use TypeScript effectively instead of runtime checks
3. **Fail fast** - Let programming errors surface immediately during development
4. **Validate at boundaries** - Check external data, but trust internal data flow
5. **Add context only when needed** - Comment when the "why" isn't obvious from the "what"

## Code Review Questions

When reviewing code, ask:

- Could this comment be eliminated by better naming or structure?
- Does this error handling add genuine value or just noise?
- Would removing this defensive check help us catch bugs faster?
- Is this validation protecting against real risks or imaginary ones?

## Summary

Good code tells a story through its structure and naming. Excessive comments and defensive programming often indicate opportunities to improve the code itself rather than explain or protect it. Focus on writing clear, purposeful code that handles real failure cases while allowing programming errors to surface quickly.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.