Harness-engineering harness-codebase-cleanup
<!-- Generated by harness generate-slash-commands. Do not edit. -->
git clone https://github.com/Intense-Visions/harness-engineering
T=$(mktemp -d) && git clone --depth=1 https://github.com/Intense-Visions/harness-engineering "$T" && mkdir -p ~/.claude/skills && cp -r "$T/agents/commands/codex/harness/harness-codebase-cleanup" ~/.claude/skills/intense-visions-harness-engineering-harness-codebase-cleanup && rm -rf "$T"
agents/commands/codex/harness/harness-codebase-cleanup/SKILL.mdHarness Codebase Cleanup
Orchestrate dead code removal and architecture violation fixes with a shared convergence loop. Catches cross-concern cascades that individual skills miss.
When to Use
- After a major refactoring or feature removal when both dead code and architecture violations are likely
- As a periodic comprehensive codebase hygiene task
- When
orcleanup-dead-code
individually are not catching cascading issuesenforce-architecture - When you want hotspot-aware safety classification
- NOT for quick single-concern checks -- use
orcleanup-dead-code
directlyenforce-architecture - NOT when tests are failing -- fix tests first
- NOT during active feature development
Flags
| Flag | Effect |
|---|---|
| Enable convergence-based auto-fix (default: detect + report only) |
| Skip architecture checks |
| Skip dead code checks |
| Show what would be fixed without applying |
| Non-interactive: apply safe fixes only, report everything else |
Process
Phase 1: CONTEXT -- Build Hotspot Map
- Run hotspot detection via git log analysis:
git log --format=format: --name-only --since="6 months ago" | sort | uniq -c | sort -rn | head -50 - Build churn map. Parse output into a
mapping.file -> commit count - Compute top 10% threshold. Sort all files by commit count. The file at the 90th percentile defines the threshold. Files above this threshold are "high churn."
- Store as HotspotContext for use in Phase 3 (CLASSIFY).
Phase 2: DETECT -- Run Both Concerns in Parallel
-
Dead code detection (skip if
):--architecture-only- Run
harness cleanup --type dead-code --json - Captures: dead files, dead exports, unused imports, dead internals, commented-out code blocks, orphaned dependencies
- Run
-
Architecture detection (skip if
):--dead-code-only- Run
harness check-deps --json - Captures: layer violations, forbidden imports, circular dependencies, import ordering issues
- Run
-
Merge findings. Convert all raw findings into
objects usingCleanupFinding
. This normalizes both concerns into a shared schema.classifyFinding()
Phase 3: CLASSIFY -- Safety Classification and Dedup
-
Apply safety classification. Each
already has a safety level fromCleanupFinding
. Review the classification rules:classifyFinding()Dead code safety:
Finding Safety Condition Dead files Safe Not entry point, no side effects Unused imports Safe Zero references Dead exports (non-public) Safe Zero importers, not in package entry point Dead exports (public API) Unsafe In package entry point or published package Commented-out code Safe Always (code is in git history) Orphaned npm deps Probably safe Needs install + test verification Dead internals Unsafe Cannot reliably determine all callers Architecture safety:
Violation Safety Condition Import ordering Safe Mechanical reorder Forbidden import (with alternative) Probably safe 1:1 replacement configured Forbidden import (no alternative) Unsafe Requires restructuring Design token (unambiguous) Probably safe Single token match Design token (ambiguous) Unsafe Multiple candidates Upward dependency Unsafe Always Skip-layer dependency Unsafe Always Circular dependency Unsafe Always -
Apply hotspot downgrade. For each finding, check if the file is in the top 10% by churn (from Phase 1 HotspotContext). If so, downgrade
tosafe
. Do not downgradeprobably-safe
findings.unsafe -
Cross-concern dedup. Call
to merge overlapping findings:deduplicateFindings()- A dead import from a forbidden layer = one finding (dead-code concern, noting architecture overlap)
- A dead file that has architecture violations = one finding (dead-code, noting violations resolved by deletion)
Phase 4: FIX -- Convergence Loop
Only runs when
flag is set. Without --fix
--fix, skip to Phase 5 (REPORT).
findings = classified findings from Phase 3 previousCount = findings.length iteration = 0 while iteration < 5: iteration++ # Batch 1: Apply safe fixes silently safeFixes = findings.filter(f => f.safety === 'safe') apply(safeFixes) # Batch 2: Present probably-safe fixes if --ci mode: skip probably-safe fixes (report only) else: probablySafeFixes = findings.filter(f => f.safety === 'probably-safe') presentAsDiffs(probablySafeFixes) apply(approved fixes) # Verify: lint + typecheck + test verifyResult = run("pnpm lint && pnpm tsc --noEmit && pnpm test") if verifyResult.failed: revertBatch() reclassify failed fixes as unsafe continue # Re-detect both concerns newFindings = runDetection() # Phase 2 again newFindings = classify(newFindings) # Phase 3 again if newFindings.length >= previousCount: break # No progress, stop previousCount = newFindings.length findings = newFindings
Verification gate: Every fix batch must pass lint + typecheck + test. If verification fails:
- Revert the entire batch (use git:
)git checkout -- . - Reclassify all findings in the batch as
unsafe - Continue the loop with remaining findings
Cross-concern cascade examples:
- Dead import from forbidden layer: removing the dead import also resolves the architecture violation. Single fix, both resolved.
- Architecture fix creates dead code: replacing a forbidden import makes the old module's export dead. Next detect cycle catches it.
- Dead file resolves multiple violations: deleting a dead file that imports from wrong layers resolves those violations too.
Phase 5: REPORT -- Actionable Output
Generate a structured report with two sections:
1. Fixes Applied: For each fix that was applied:
- File and line
- What was fixed (finding type and description)
- What action was taken (delete, replace, reorder)
- Verification status (pass/fail)
2. Remaining Findings (requires human action): For each unsafe finding that was not auto-fixed:
- What is wrong: The finding type, file, line, and description
- Why it cannot be auto-fixed: The safety reason and classification logic
- Suggested approach: Concrete next steps for manual resolution
Example report output:
=== HARNESS CODEBASE CLEANUP REPORT === Fixes applied: 12 - 5 unused imports removed (safe) - 3 dead exports de-exported (safe) - 2 commented-out code blocks deleted (safe) - 1 forbidden import replaced (probably-safe, approved) - 1 orphaned dependency removed (probably-safe, approved) Convergence: 3 iterations, 12 → 8 → 3 → 3 (stopped) Remaining findings: 3 (require human action) 1. UNSAFE: Circular dependency File: src/services/order-service.ts <-> src/services/inventory-service.ts Why: Circular dependencies require structural refactoring Suggested: Extract shared logic into src/services/stock-calculator.ts 2. UNSAFE: Dead internal function File: src/utils/legacy.ts:45 — processLegacyFormat() Why: Cannot reliably determine all callers (possible dynamic usage) Suggested: Search for string references, check config files, then delete if confirmed unused 3. UNSAFE: Public API dead export File: packages/core/src/index.ts — legacyHelper Why: Export is in package entry point; external consumers may depend on it Suggested: Deprecate with @deprecated JSDoc tag, remove in next major version
Examples
Example: Post-Refactoring Cleanup
After removing the
legacy-auth module:
- Phase 1 (CONTEXT): Hotspot analysis shows
has 42 commits (top 5%).src/services/auth.ts - Phase 2 (DETECT): Dead code detects 3 dead exports in
(were only used by legacy-auth). Architecture detects 1 forbidden import insrc/utils/token.ts
(still importing from removed module's location).src/services/session.ts - Phase 3 (CLASSIFY): Dead exports classified as
but downgraded tosafe
becauseprobably-safe
is in a high-churn file. Forbidden import classified astoken.ts
(no alternative configured).unsafe - Phase 4 (FIX): First iteration removes 3 dead exports (approved as probably-safe). Re-detect finds
now has zero exports and becomes a dead file. Second iteration deletes the dead file. Convergence stops -- the forbidden import requires manual restructuring.token.ts - Phase 5 (REPORT): 4 fixes applied (3 dead exports + 1 dead file), 1 remaining finding (forbidden import requiring restructuring).
Harness Integration
-- Dead code detection inputharness cleanup --type dead-code --json
-- Architecture violation detection inputharness check-deps --json
analysis -- Hotspot context for safety classification (inline command, no skill invocation needed)git log
-- Final validation after all fixesharness validate
-- Final architecture check after all fixesharness check-deps
Success Criteria
- All safe fixes are applied without test failures
- Probably-safe fixes are presented as diffs for approval (or skipped in CI mode)
- Unsafe findings are never auto-fixed
- Convergence loop catches cross-concern cascades
- Report includes actionable guidance for every remaining finding
passes after cleanupharness validate
Rationalizations to Reject
| Rationalization | Reality |
|---|---|
| "This dead export is in a high-churn file but the removal is clearly safe" | High-churn files have more hidden consumers. Safe findings in the top 10% by churn are downgraded to probably-safe, requiring explicit approval. |
| "The convergence loop is not reducing findings quickly enough, so I will apply unsafe fixes to make progress" | Unsafe findings are never auto-fixed, regardless of convergence pressure. Each requires human judgment. |
| "The verification gate failed on a probably-safe fix, but I am confident the fix is correct" | When verification fails after a fix batch, the entire batch must be reverted and all findings reclassified as unsafe. |
| "I will skip the hotspot context phase since it adds time and the churn data is just supplementary" | The hotspot map drives safety classification accuracy. Without it, safe fixes in high-churn areas are not downgraded. |
Escalation
- When convergence loop does not converge after 5 iterations: The codebase has deeply tangled issues. Stop and report all remaining findings. Consider breaking the cleanup into focused sessions.
- When a safe fix causes test failures: The classification was wrong. Revert, reclassify as unsafe, and investigate the hidden dependency. Document the false positive for future improvement.
- When the hotspot detector is unavailable: Skip the hotspot downgrade. All safety classifications use their base level without churn context.
- When dead code and architecture fixes conflict: The convergence loop handles this naturally. If removing dead code creates an architecture issue (rare), the next detection cycle catches it.