# Cleanup Dead Code

> Entropy analysis and safe cleanup. Find unused exports, dead files, and pattern violations — then remove them without breaking anything.

## When to Use

- After a major refactoring or feature removal
- When the codebase feels "heavy" — too many files, unclear what is used
- As a periodic hygiene task (monthly or per-quarter)
- When `on_entropy_check` triggers fire
- After deleting a feature flag and its associated code paths
- When `harness cleanup` reports growing entropy in the project health dashboard
- NOT during active feature development — dead code cleanup is a separate, focused task
- NOT when tests are failing — fix tests first, then clean up
- NOT under time pressure — dead code removal requires careful verification

## Process

### Phase 1: Analyze — Run Entropy Report

1. **Run `harness cleanup`** to generate a full entropy report. This analyzes:
   - **Dead exports** — functions, classes, and constants that are exported but never imported anywhere
   - **Unused files** — files that are not imported by any other file in the project
   - **Pattern violations** — code that violates established project patterns (e.g., a service file without a corresponding test file)
   - **Orphaned dependencies** — npm packages listed in package.json but never imported

2. **Run `harness cleanup --type dead-code --json`** for machine-readable output focused specifically on unused code.

3. **Review the report summary.** Note the total count and distribution. A few dead exports are normal; dozens suggest accumulated entropy from incomplete refactorings.

### Phase 2: Categorize — Safe vs. Needs Review

**Safe to auto-fix (remove without further analysis):**

- Exports that are not imported anywhere AND not referenced in any config file
- Files that are not imported anywhere AND have no side effects (no top-level execution)
- Commented-out code blocks (dead by definition)
- Unused local variables and imports within a file (linter can catch these)

**Needs human review before removal:**

- Exports that APPEAR unused but might be consumed dynamically (see "What NOT to Delete" below)
- Files that appear unused but are entry points (CLI scripts, test fixtures, config files)
- Code that is only used in specific build configurations or environments
- Exports from a public package — external consumers may depend on them

### Phase 3: Apply Safe Fixes

For each item categorized as safe:

1. **Remove the dead code.** Delete the export, function, file, or import.

2. **Run `harness fix-drift`** to update any documentation references that pointed to the deleted code.

3. **Run the full test suite.** All tests must pass. If any test fails:
   - **STOP.** The code was not actually dead — something depends on it.
   - **Undo the deletion immediately.**
   - **Reclassify** the item as "needs human review" and investigate the hidden dependency.

4. **Run `harness validate` and `harness check-deps`.** Both must pass.

5. **Commit the cleanup.** Group related removals into logical commits (e.g., "remove unused shipping utilities" not "delete dead code").

### Phase 4: Report Remaining Items

For items that need human review, report:

1. **What it is** — file path, export name, what it does
2. **Why it appears dead** — no static imports found
3. **Why it might not be dead** — dynamic import patterns, external consumers, test utilities
4. **Recommended action** — delete with confidence, delete with caution, or keep

## What NOT to Delete

These patterns make code APPEAR dead when it is actually in use:

### Dynamically imported modules

```typescript
// This import won't show up in static analysis
const module = await import(`./plugins/${pluginName}`);
```

Files in a `plugins/` directory may appear unused but are loaded dynamically at runtime. Check for `import()` calls, `require()` with variables, and glob-based loading patterns.

### Test utilities and fixtures

```typescript
// test-helpers.ts — only imported by test files
export function createMockUser() { ... }
```

Test utility files may appear unused if the analysis excludes test files. Verify that `harness cleanup` includes test files in its import graph.

### Type-only exports

```typescript
// Only used as a type, never as a value
export interface UserConfig { ... }
```

Some analysis tools miss type-only imports (`import type { UserConfig }`). Verify before deleting any exported interface or type alias.

### Package entry points

```typescript
// index.ts — re-exports for external consumers
export { createClient } from './client';
```

The entry point of a package re-exports things for external consumers. These exports may have zero internal imports but are the public API.

### Side-effect files

```typescript
// polyfills.ts — imported for side effects, not for exports
import './polyfills';
```

Some files are imported for their side effects (polyfills, global registrations, CSS). They have no exports but are not dead.

### Environment-specific code

```typescript
// Only used when FEATURE_FLAG_X is enabled
if (process.env.FEATURE_FLAG_X) {
  const handler = require('./experimental-handler');
}
```

Code behind feature flags or environment checks may appear dead in the default configuration.

## Harness Integration

- **`harness cleanup`** — Full entropy analysis. Reports dead exports, unused files, pattern violations, and orphaned dependencies.
- **`harness cleanup --type dead-code`** — Focused analysis on unused code specifically.
- **`harness cleanup --type dead-code --json`** — Machine-readable output for automation.
- **`harness fix-drift`** — Update documentation after removing dead code. Ensures deleted items are not still referenced in docs.
- **`harness validate`** — Run after cleanup to verify project structure remains valid.
- **`harness check-deps`** — Run after cleanup to verify no dependency violations were introduced.

## Success Criteria

- `harness cleanup` reports zero dead exports and zero unused files (or all remaining items are documented as intentional)
- All tests pass after every deletion
- `harness validate` and `harness check-deps` pass after cleanup
- Documentation references to deleted code are updated or removed
- No dynamically-imported, type-only, or side-effect code was accidentally deleted
- Each cleanup commit is atomic and has a descriptive message explaining what was removed and why

## Examples

### Example: Removing unused utility functions

**Entropy report:**

```
DEAD EXPORT: src/utils/string-helpers.ts
  - capitalizeFirst() — 0 imports found
  - truncateWithEllipsis() — 0 imports found
  - slugify() — 3 imports found (ACTIVE, not dead)
```

**Action:** Remove `capitalizeFirst` and `truncateWithEllipsis` from the file. Keep `slugify`. Run tests — all pass. Commit: "remove unused capitalizeFirst and truncateWithEllipsis from string-helpers"

### Example: Detecting a false positive

**Entropy report:**

```
UNUSED FILE: src/plugins/markdown-renderer.ts
  - 0 static imports found
  - File contains: export default class MarkdownRenderer
```

**Investigation:** Check for dynamic imports:

```typescript
// src/plugins/index.ts
const renderer = await import(`./${format}-renderer`);
```

**Result:** False positive. The file is loaded dynamically based on the `format` variable. Mark as intentional and add a comment in the file explaining the dynamic loading pattern.

### Example: Orphaned npm dependency

**Entropy report:**

```
ORPHANED DEPENDENCY: moment (package.json)
  - 0 imports of 'moment' found in src/
  - Last imported in commit abc123 (removed 3 months ago)
```

**Action:** Remove `moment` from package.json dependencies. Run `npm install` to update lockfile. Run tests — all pass. Commit: "remove unused moment dependency"

## Escalation

- **When removing code causes unexpected test failures:** The code has a hidden dependency. Undo the deletion, investigate the dependency chain, and document the finding. The code is not dead — it is just hard to trace.
- **When the entropy report is very large (>50 items):** Do not attempt to clean everything at once. Pick the highest-confidence dead code (files with zero imports, no dynamic patterns) and clean those first. Schedule the rest across multiple sessions.
- **When you are unsure if an export is used externally:** Check if the code is in a published package. If so, removing an export is a breaking change. Deprecate first, then remove in a major version.
- **When dead code is tangled with live code in the same file:** Extract the live code first (using harness-refactoring), then delete the remaining dead code. Do not try to surgically remove dead code from a complex file in one step.
