Audit a codebase for maintenance and modernization. Challenges scope,
reviews architecture/quality/tests/performance/dependencies, files
deferred work via bd. Language-specific addendums for iOS/Swift, Go,
and Web/JS/CSS activate automatically based on what's in the repo.
Supports monorepos with mixed stacks.
Audit a codebase for maintenance and modernization. Challenges scope,
reviews architecture/quality/tests/performance/dependencies, files
deferred work via bd. Language-specific addendums for iOS/Swift, Go,
and Web/JS/CSS activate automatically based on what's in the repo.
Supports monorepos with mixed stacks.
allowed-tools
["Read","Grep","Glob","Bash","AskUserQuestion"]
Code Overhaul Review
Audit this codebase for maintenance, modernization, and overhaul. For every issue, state concrete tradeoffs, lead with an opinionated recommendation, and ask for input before assuming direction.
Health check, not feature review. Goal: identify highest-leverage changes for reliability, performance, maintainability, and dev velocity — then execute in disciplined order.
Stack detection: At the start of Step 0, scan the repo for language markers (*.swift/Xcode projects, go.mod, package.json/tsconfig). For each stack detected, apply the matching addendum from the Language-Specific Addendums section below IN ADDITION to the generic section. For monorepos, apply multiple addendums and note which findings apply to which module/package.
Priority hierarchy
Context low? Step 0 > Impact/effort matrix > Test diagram > Recommendations > Rest. Never skip Step 0 or the matrix.
Engineering preferences
DRY — flag repetition aggressively.
Well-tested non-negotiable; too many > too few.
"Engineered enough" — not fragile, not over-abstracted.
More edge cases, not fewer; thoughtfulness > speed.
Explicit over clever.
Minimal diff: fewest new abstractions and files touched.
Performance is a feature. Profile before and after.
Prefer platform/stdlib over third-party when feasible.
Deprecation warnings are bugs. Fix proactively.
Build time matters. Justify anything that slows it.
Diagrams
ASCII art for data flow, state machines, dependency graphs, pipelines, decision trees — in plans and inline code comments. Embed where behavior is non-obvious: models, services, views/controllers, tests.
Diagram maintenance is part of the change. Stale diagrams are worse than none. Flag even outside scope.
BEFORE YOU START
Step 0: Scope Assessment
Repo health: Compiler/linter warnings, deprecation warnings, TODO/FIXME/HACK density, dead code, unused imports, test pass rate, build time. (Add stack-specific tools per addendum.)
Dependency landscape: All third-party deps, current vs. latest. Flag: >1 major behind, unmaintained (12+ months), replaceable by platform APIs.
Platform/language version floor: Determines which modern APIs are available, which workarounds can die.
Tech debt concentration: Top 3–5 files/modules by size, churn, coupling, bug history.
Complexity check: >15 files or >3 new abstractions → challenge scope.
Offer three modes:
SURGICAL: One theme, minimal blast radius, one session.
SYSTEMATIC: Section-by-section interactive, ≤4 issues per section.
FULL AUDIT: All sections, all issues. Phased roadmap.
Once chosen, commit fully. No silent scope reduction.
Review Sections
1. Architecture
Evaluate: module structure and boundaries (draw dependency graph), layering violations, data flow and sources of truth, concurrency/thread safety, routing/navigation consistency, scaling bottlenecks, security boundaries. For each major boundary: one realistic production failure and whether current code handles it. Identify where ASCII diagrams belong. Apply stack addendum.
STOP. AskUserQuestion. Do NOT proceed until user responds.
2. Code quality
Evaluate: file/folder organization, DRY violations, error handling gaps (cite file and line), naming consistency, tech debt hotspots, over-engineering and under-engineering, dead code, stale diagrams, linter/compiler warnings. Apply stack addendum.
STOP. AskUserQuestion. Do NOT proceed until user responds.
3. Tests
Diagram all critical flows, pipelines, state transitions, branching. For each: test exists? meaningful? edge cases covered? fast and reliable? Also: test distribution, execution time (flag slow tests), isolation, missing categories, mock strategy. Apply stack addendum.
STOP. AskUserQuestion. Do NOT proceed until user responds.
4. Performance
Evaluate: startup/launch time, memory footprint and leaks, response latency on hot paths, I/O patterns, network efficiency, build time, binary/bundle size. Apply stack addendum.
STOP. AskUserQuestion. Do NOT proceed until user responds.
Xcode hygiene: unused build phases, stale schemes, code signing drift, build settings at wrong level.
Summary additions
Add rows: Min iOS target, Swift version, force-unwrap count, SwiftLint violations.
Extra anti-pattern
UIKit-to-SwiftUI migration without a boundary strategy → define the bridge pattern once, use everywhere.
Addendum: Go
Triggers: go.mod, *.go files.
Step 0 additions
Run: go vet, staticcheck, golangci-lint, govulncheck ./..., go mod tidy drift check.
Go version in go.mod determines: range-over-func (1.23+), log/slog (1.21+), errors.Join (1.20+), generics depth, loop variable fix (1.22+).
Dep audit specifics: go list -m -u all. Replaceable: gorilla/mux→stdlib 1.22+ routing, logrus→log/slog, pkg/errors→fmt.Errorf %w, testify→stdlib testing, go-playground/validator→custom, gorm→sqlc/sqlx, cobra→stdlib flag for simple CLIs.
Architecture additions
Package boundaries: internal/ usage correct? Circular dep risks?
Interface pollution: too many interfaces defined by implementor rather than consumer. Accept interfaces, return structs.
Dependency injection: wire, manual, or scattered init()?
Graceful shutdown chain: signal → context cancellation → resource cleanup.
Error propagation: sentinel vs typed vs wrapping — consistent?
Context: values vs cancellation — abuse?
Code quality additions
Unchecked errors:_ = foo() — cite every one unless justified with comment.
Over-engineering: interfaces with one implementation, unnecessary generics, Options pattern for 2 config values.
Under-engineering: 2000+ line files, >5 params, any/interface{} where generics clarify.
Test additions
Table-driven tests consistent? t.Helper() used? Subtests with t.Run()?
Integration tests tagged //go:build integration?
Race detector:go test -race passing? This is a gate, not optional.
Benchmarks for hot paths (BenchmarkX). Fuzz tests for parsers (FuzzX).
Golden files for complex output. testdata/ organized?
Mocking: interfaces at boundaries only, not mocking everything. httptest for handlers.
Performance additions
CPU: Unnecessary allocations in tight paths, reflection in hot code, regexp compilation inside loops (compile once as package var), string concat in loops (strings.Builder).
Memory: Goroutine leaks (unbounded spawn without context cancel), sync.Pool opportunities, slice pre-alloc (make([]T, 0, cap)), string↔[]byte in hot paths.
Runtime: Unnecessary re-renders (missing memo where measured), DOM thrashing, event listener cleanup, Web Worker opportunities, requestAnimationFrame for visual updates.
Caching: Service worker strategy, HTTP headers, CDN, stale-while-revalidate, asset fingerprinting.
Network: API waterfall (sequential→parallel), overfetching, missing pagination.