Files
MyAiConfiguration/shared/rules/refactoring.md
T

4.7 KiB

Refactoring Guidelines

Core Rule

  • Refactor only when it improves readability, maintainability, correctness, performance, safety, or architecture.
  • Do not refactor unrelated code without a concrete reason.
  • Do not change behavior unless the refactoring explicitly requires it.
  • Preserve existing functionality by default.
  • Keep refactorings focused and minimal.
  • Prefer simple improvements over large rewrites.

Scope

  • Limit changes to the smallest reasonable scope.
  • Do not mix unrelated refactorings.
  • Do not combine feature work, bug fixes, formatting changes, and broad refactoring unless necessary.
  • Avoid repository-wide changes unless explicitly required.
  • Do not rename, move, split, or merge files unnecessarily.
  • Do not introduce new abstractions without a clear benefit.

Behavior Preservation

  • Existing public behavior must remain unchanged unless explicitly requested.
  • Preserve API contracts unless a breaking change is explicitly intended.
  • Preserve serialization formats, database contracts, configuration keys, routes, and external integrations unless explicitly required.
  • Preserve exception behavior where it is part of an existing contract.
  • Preserve thread-safety and concurrency behavior.
  • Preserve performance characteristics unless the refactoring intentionally improves them.

Code Quality

  • Prefer modern, readable C# syntax.
  • Reduce unnecessary complexity.
  • Remove duplication where doing so improves clarity.
  • Prefer clear control flow over clever code.
  • Reduce nesting where practical.
  • Improve naming when current names are misleading or unclear.
  • Prefer strongly typed code.
  • Avoid unnecessary interfaces and abstractions.
  • Avoid unnecessary wrapper classes and indirection.
  • Prefer composition over inheritance.
  • Remove dead code when it is clearly unused.
  • Remove obsolete comments and commented-out code.
  • Keep methods and classes focused.

Architecture

  • Respect existing architectural boundaries.
  • Do not introduce new layers without a concrete need.
  • Avoid circular dependencies.
  • Reduce coupling where practical.
  • Keep dependencies explicit.
  • Do not move business logic into infrastructure or presentation layers.
  • Do not weaken encapsulation for convenience.
  • Avoid global or static mutable state.

Performance

  • Do not trade significant readability for theoretical micro-optimizations.
  • Avoid introducing unnecessary allocations in hot paths.
  • Avoid unnecessary collection copies.
  • Avoid unnecessary LINQ in performance-critical code.
  • Preserve or improve algorithmic complexity.
  • Measure performance-sensitive refactorings when relevant.
  • Do not assume a refactoring is faster without evidence.

Safety

  • Do not weaken validation, authorization, authentication, encryption, null-safety, or input handling.
  • Preserve or improve error handling.
  • Preserve cancellation behavior.
  • Preserve disposal and resource lifetime semantics.
  • Avoid introducing race conditions.
  • Avoid exposing mutable internal state.
  • Treat external input as untrusted.
  • Do not introduce unsafe code unless explicitly required.

Dependencies

  • Do not add new dependencies unless they provide a clear and necessary benefit.
  • Prefer existing project dependencies and the .NET BCL.
  • Do not replace stable dependencies without a concrete reason.
  • Avoid refactorings that increase long-term maintenance cost.

Tests

  • Existing relevant tests must continue to pass.
  • Update tests when internal structure changes make it necessary.
  • Do not delete valid tests merely because they fail after a refactoring.
  • Add tests when the refactoring exposes previously untested critical behavior.
  • Prefer behavior-based tests over implementation-detail tests.

Validation

After a refactoring:

  • Build the affected project or solution.
  • Run relevant tests.
  • Check for new warnings.
  • Verify affected code paths.
  • Review the diff for accidental behavior changes.
  • Check that unrelated files were not modified unnecessarily.
  • Confirm that the result is simpler or clearer than before.

Large Refactorings

  • Break large refactorings into small, understandable steps.
  • Avoid big-bang rewrites when incremental changes are practical.
  • Keep intermediate states buildable where possible.
  • Do not perform broad architectural rewrites without explicit user intent.
  • If multiple valid architectural directions exist, ask the user before choosing one.

Decision Rule

  • If a refactoring may change externally visible behavior, data contracts, architecture, public APIs, persistence, security, or deployment behavior, ask the user first.
  • If the benefit is unclear or the change introduces significant complexity, do not proceed autonomously.
  • When uncertain, prefer the smaller and safer refactoring.