---
name: codebase-discovery
description: MUST run before superpowers:writing-plans. Use when you have a design spec and are about to write an implementation plan. Systematically searches the codebase for existing utilities, reference implementations, UI patterns, and conventions before planning begins. Triggers on "discover what exists", "find reusable code", invoking writing-plans, or any transition from spec to plan.
---

# Codebase Discovery

## Overview

Systematically explore the codebase to find existing code that the implementation plan should reuse, match, or extend. Produces a discovery report that constrains the plan — preventing the agent from reinventing utilities, ignoring conventions, or writing inconsistent UI.

**Core principle:** Every new function, pattern, or convention in a plan is a liability. Discovery turns "write from scratch" into "reuse and extend."

**Announce at start:** "I'm using the codebase-discovery skill to find existing code before planning."

## When to Use

```dot
digraph when {
    "Have a design spec?" [shape=diamond];
    "About to write implementation plan?" [shape=diamond];
    "Run codebase-discovery" [shape=box];
    "Skip — discovery not needed" [shape=box];

    "Have a design spec?" -> "About to write implementation plan?" [label="yes"];
    "Have a design spec?" -> "Skip — discovery not needed" [label="no"];
    "About to write implementation plan?" -> "Run codebase-discovery" [label="yes"];
    "About to write implementation plan?" -> "Skip — discovery not needed" [label="no"];
}
```

- After brainstorming produces a spec, before invoking writing-plans
- When user says "discover", "find existing code", "what can we reuse"
- When the spec describes functionality that likely has precedent in the codebase

**Do NOT use for:**
- Greenfield projects with no existing code
- Trivial changes (typo fix, config change)
- Pure refactoring where you already know all affected files

## The Process

### Step 1: Extract Discovery Targets from the Spec

Read the spec and list concrete things to search for. Categorize each into:

| Category | What to search for | Example from bundle save hook |
|----------|-------------------|-------------------------------|
| **API calls** | Existing helpers, payload builders, client wrappers | category creation payload builder |
| **UI patterns** | How sibling components handle the same concern | error banner variant + styling in other side panels |
| **Data transforms** | Math utilities, serialization helpers, type converters | Decimal.js for price arithmetic |
| **Error handling** | Error parsing utilities, error display patterns | `getErrorResponseText` for API errors |
| **Form patterns** | Validation wiring, submission guards, form state | double-submit guard, validate prop on Form |
| **Types** | Existing union types, shared interfaces, no-any conventions | Form value union types |
| **i18n** | How the module handles user-facing strings | `intl.formatMessage` vs hardcoded strings |
| **Conventions** | Guard patterns, constants extraction, import ordering | `DEFAULT_DELIVERY_METHODS` constant |

### Step 2: Find Reference Implementations

Find the **nearest analogous feature** — the component/hook/flow most similar to what the spec describes.

**How to search:**
1. Identify what the spec builds (e.g., "a save hook for a side panel form")
2. Find sibling components in the same module (e.g., other side panels, other save hooks)
3. If none in the same module, expand to the same app, then the monorepo

**What to extract from the reference:**
- How it handles the same concerns the spec describes (loading, errors, validation, submission)
- Which utilities it imports
- Its typing approach
- Its test patterns

**Record:** file path, what to learn from it, specific lines/patterns to match.

### Step 3: Search for Existing Utilities

For each API call, data transform, or utility described in the spec:

1. **Grep for the concept** — search for function names, keywords, import patterns
   - e.g., `grep -r "buildOfferingApi" --include="*.ts"` to find payload builders
   - e.g., `grep -r "Decimal" --include="*.ts"` to find math precision usage
2. **Check the module's imports** — what do sibling files already import?
3. **Check shared packages** — `common/utils`, `common/hooks`, shared API layers

**Record:** function name, import path, what it does, why it should be used instead of writing custom code.

### Step 4: Catalog UI Patterns

For each UI concern in the spec (error display, loading states, empty states, validation messages):

1. Find the nearest sibling component that handles the same concern
2. Note the exact component, variant, and styling used
3. If the sibling is inconsistent with design system conventions, note both

**Record:** component path, specific pattern (e.g., `Banner variant="negative" style={{ margin: '8px 24px' }}`), where it's used.

### Step 5: Note Conventions

Scan the module for patterns that aren't documented but are consistently followed:

- **Type safety:** Does the module use `any`? Type casts? Union types?
- **Guard patterns:** Are there double-submit guards? Abort controllers? Ref-based locks?
- **Constants:** Are magic values extracted to constants?
- **Error handling:** How are API errors parsed and displayed?
- **Testing:** What test utilities are used? How are mocks set up? Are tests locale-independent?

### Step 6: Write the Discovery Report

Save to: `docs/superpowers/discovery/YYYY-MM-DD-<feature>-discovery.md`
(If user has a different convention for discovery location, follow that.)

**Report template:**

```markdown
# Discovery Report: [Feature Name]

**Spec:** `path/to/spec.md`
**Date:** YYYY-MM-DD
**Module:** path/to/module/

## Reference Implementations

| File | What to learn | Key patterns |
|------|--------------|--------------|
| `path/to/SiblingComponent.tsx` | Error banner styling, form submission | `Banner variant="negative"`, useRef submit guard |

## Utilities to Reuse

| Utility | Import path | Use instead of |
|---------|------------|----------------|
| `buildOfferingApiCategoryPayload` | `module/components/AddCategoriesPage/utils` | Manual category payload construction |
| `getErrorResponseText` | `common/utils` | `err.message` for API errors |

## UI Patterns to Match

| Concern | Pattern | Source |
|---------|---------|--------|
| Error banner | `<Banner variant="negative" style={{ margin: '8px 24px' }}>` | `SiblingPanel.tsx:86` |
| Validation | `validate` prop wired to Form component | `OtherForm.tsx:42` |

## Conventions Observed

- **Types:** Module uses union types for form values, no `any` in hook signatures
- **Guards:** Save hooks use `useRef` for double-submit prevention
- **Math:** Price calculations use `Decimal.js` (already in dependencies)
- **i18n:** Error messages use `intl.formatMessage`, not hardcoded English
- **Constants:** Repeated literal arrays extracted to module-level constants

## Constraints for the Plan

These are directives for the plan author. Each constraint prevents a specific category of bug.

### DO use:
- `buildOfferingApiCategoryPayload` for category creation payloads
- `getErrorResponseText` for parsing API error responses
- `Decimal.js` for any price/percentage arithmetic
- `intl.formatMessage` for all user-facing error strings
- `useRef` guard for preventing double form submission
- `Banner variant="negative"` with `margin: '8px 24px'` for error display

### DO NOT:
- Use `any` type in hook signatures — use form value union types
- Hardcode `delivery_methods` array — extract to a shared constant
- Write locale-dependent test assertions (no `€`, use regex patterns)
- Construct API payloads manually when a builder function exists
- Use `variant="warning"` for error banners (module convention is `"negative"`)
```

### Step 7: Update the Spec

Append a reference to the discovery report at the bottom of the spec:

```markdown
## Discovery Report

See `docs/superpowers/discovery/YYYY-MM-DD-<feature>-discovery.md` for existing utilities,
reference implementations, and constraints that must be followed in the implementation plan.
```

### Step 8: Hand off to writing-plans

After the discovery report is saved and the spec is updated:

> "Discovery complete. Report saved to `<path>`. Found N utilities to reuse, N reference implementations, and N constraints for the plan. Ready to proceed with writing-plans."

Then invoke the writing-plans skill. The plan author MUST read the discovery report before writing the plan.

## Quality Checks

After writing the discovery report, verify:

1. **Every API call in the spec** has been checked for existing helpers
2. **Every UI concern** has been compared to sibling components
3. **At least one reference implementation** was found and analyzed
4. **Constraints section** has concrete "DO use" / "DO NOT" directives with file paths
5. **No vague constraints** — every directive references a specific function, component, or pattern

## Common Mistakes

| Mistake | Fix |
|---------|-----|
| Searching only in the current directory | Expand search to module, then app, then monorepo |
| Finding a utility but not recording its import path | Always include the exact import path |
| Listing utilities without explaining when to use them | Add "Use instead of [what the plan might write]" |
| Missing conventions because they're "obvious" | If it's not in CLAUDE.md or AGENTS.md, it's not obvious to the agent |
| Skipping test patterns | Test conventions (locale-independence, mock setup) prevent just as many bugs |

## Integration with Superpowers

This skill inserts between brainstorming and writing-plans:

```
brainstorm → spec → DISCOVERY → writing-plans → execute
```

The discovery report becomes a required input for writing-plans. When the plan author writes implementation steps, they reference the discovery report's constraints section instead of inventing code from scratch.

**Key change to plan quality:** Instead of a plan step that says:

```ts
// 200 lines of handwritten useSaveBundle code with `any` types and manual payloads
```

The plan step says:

```
Create useSaveBundle.ts:
- Use buildOfferingApiCategoryPayload (discovery: Utilities #1) for category creation
- Use getErrorResponseText (discovery: Utilities #2) for error parsing
- Type saveBundle as (formValues: BundleFormValues) => Promise<void> — NO any
- Add useRef double-submit guard (discovery: Conventions)
- See SiblingPanel.tsx for error banner pattern (discovery: UI Patterns #1)
```

This forces the implementing agent to read the actual codebase rather than copying plan code.
