Ripple Effect Prevention

Prevent cascading breaks when AI modifies code with dependencies.

What is the Ripple Effect?

When AI modifies a function, it might not realize other code depends on it:

// Original function
function getUserById(id: string): User {
  return db.users.find(u => u.id === id);
}

// AI "improves" it to be async
async function getUserById(id: string): Promise<User> {
  return await db.users.findAsync(u => u.id === id);
}

// 15 other files now break because they
// weren't updated to await the result

This is the "ripple effect" - one change breaks many dependent files.

Preventing Ripple Effects

1. Document Dependencies

Use protection annotations to indicate what depends on a function:

/**
 * @protected
 * DEPENDENCIES: UserProfile, Dashboard, Settings, AdminPanel
 * CALLERS: 8 files total
 */
function getUserById(id: string): User { ... }

2. Ask AI About Impact

Before making changes, ask your AI assistant about dependencies:

"What files call getUserById? What would break if I change the return type?"

3. Use Protection Annotations

Mark high-dependency functions for protection:

Functions with many callers should be marked @protected or @maintainable to signal AI should be careful.

4. Request Full Updates

When a breaking change is needed, tell AI to update all callers:

"Change getUserById to async and update all callers
to await the result. Check these files:
- src/components/UserProfile.tsx
- src/components/Dashboard.tsx
- src/pages/settings.tsx
..."

Interface Contracts

Define contracts that must be maintained even if implementation changes:

/**
 * @maintainable
 * INTERFACE CONTRACT:
 * - Input: (id: string)
 * - Output: User | null (synchronous)
 * - Throws: never (returns null on not found)
 *
 * Implementation can change, but interface must not.
 */
function getUserById(id: string): User | null {
  // Free to refactor internals
}

AI understands it can improve the implementation but must preserve the contract.

Prevention Strategies

Wrapper Functions

Create a stable wrapper that calls the changing implementation. Dependents use the wrapper.

Version Functions

Keep old function, create getUserByIdV2() for new behavior. Migrate callers gradually.

Type Guards

Use TypeScript to catch interface changes at compile time before they cause runtime errors.

Test Coverage

Tests catch ripple effects. Lumina can suggest running specific tests after changes.

Best Practices

  • 1.Identify high-dependency functions - Search for functions called from multiple files
  • 2.Document interfaces - Make contracts explicit in comments
  • 3.Ask AI about impact - "What files would break if I change this?"
  • 4.Review suggested changes - Check for interface modifications
  • 5.Run tests after changes - Catch ripples early