Tutorial · 15 min

Impact Analysis Before Refactoring

Systematically assess blast radius before changing code. Find hotspots, check risk, detect smells, verify safety.

Follow along: This tutorial uses the Ix repo. If you haven’t already, clone it and map it:
git clone https://github.com/ix-infrastructure/Ix.git && cd Ix && ix map
We’ll simulate refactoring ArangoClient — the database access layer — but the technique applies to any entity in any codebase.
01Find the Hotspots

Don’t start with the code you happen to be looking at. Start with what the graph says matters most.

ix rank --by dependents --kind class --top 10
  1. NodeId              58 dependents   core identifier
  2. Rev                 48 dependents   versioning type
  3. IxClient            45 dependents   CLI HTTP client
  4. ArangoClient        27 dependents   database layer
  5. Ok                  24 dependents   result type

Try different metrics for different perspectives:

ix rank --by callers --kind function --top 10      # most-called
ix rank --by importers --kind class --top 10       # most-imported
ix rank --by members --kind class --top 10         # largest (complexity)
02Understand the Target

Before touching anything, understand its role and structural importance.

ix explain ArangoClient
ArangoClient (class) — ArangoClient.scala

  Role: api-client (high confidence)
  Importance: high — pipeline-choke-point
    27 direct dependents
    Only 1 direct caller
    85 downstream dependents across 4 levels

  Members: execute, query, beginTransaction,
           commitTransaction, ensureSchema, ... (16 total)

  Imported by: ArangoGraphWriteApi, ArangoGraphQueryApi,
               BulkWriteApi, SmellService, MapService, ...

Key insight: everything routes through ArangoClient. It’s imported by every service in the memory layer.

03Check Blast Radius

impact classifies risk into four categories.

ix impact ArangoClient
ArangoClient — risk: CRITICAL (foundation)

  At-risk: execute (13 callers), query (8 callers)

  Risk: CRITICAL — 85 downstream entities across ALL subsystems.
  This is a foundation class. Changes propagate through every service.
Foundation

Deeply embedded, many downstream paths

ArangoClient, NodeId
Boundary

Connects subsystems

IxClient
Shared

Widely used within one subsystem

MapService
Localized

Few dependents, safe to change

isHealthy
04Trace the Specific Method

Who calls the method you’d change? If you change execute’s signature, all callers must update.

ix callers execute --pick 1
execute is called by:
  doCommit                   ArangoGraphWriteApi     (write path)
  storePatch                 ArangoGraphWriteApi     (write path)
  executeOp                  ArangoGraphWriteApi     (write path)
  retireAbsentClaimsBatch    ArangoGraphWriteApi     (write path)
  updateRevision             ArangoGraphWriteApi     (write path)
  tombstoneExistingNodes     BulkWriteApi            (bulk write)
  retireOldClaims            BulkWriteApi            (bulk write)
  resolve                    ConflictService         (conflicts)
  storeConflictSet           ConflictService         (conflicts)
  retireOldScores            SubsystemService        (scoring)
  truncateCodeGraph          Routes                  (admin reset)
  ...

13 callers across 5 files and 4 services. A signature change is a coordinated update.

05Check for Code Smells

Before refactoring, see if there are existing problems worth fixing at the same time.

ix smells
58 code smells detected:

  God modules (22):
    MapService.scala           58 chunks   conf: 0.80
    ArangoGraphQueryApi.scala  29 chunks   conf: 0.65
    ArangoGraphWriteApi.scala  26 chunks   conf: 0.65

  Orphan files (13):
    test-fixtures/ruby/...     0 connections

  Weak components (23):
    ix-cli/src/cli/stderr.ts   1 neighbor
06Score Subsystem Health
ix subsystems
Module            Clarity     Signals
Cli               75%  ✓      calls · path
Api               75%  ✓      calls · path
Context           51%  ⚠      path · calls
Map               53%  ⚠      calls · path
Explain           46%  ✗      path · calls

Smells are micro-level (individual files). Subsystems are macro-level (system health). Together they tell you where to focus a refactor.

07The Pattern

For any refactoring target — seven commands, no file reading:

ix rank --by dependents --kind class --top 10   # find what matters
ix explain TargetClass                           # understand role
ix impact TargetClass                            # check blast radius
ix callers targetMethod                          # trace callers
ix depends targetMethod --depth 2                # full tree
ix smells                                        # micro-level health
ix subsystems                                    # macro-level health