BXUP Track progress & test yourself — free
Software Engineering · Playbook · Core · ~4 min read
SOFTWARE ENGINEERING · PLAYBOOK · CORE

Legacy Comprehension to Migration Charter: Inventory Before You Touch Anything

Failed migrations usually fail at step zero: nobody actually knew what the module did. Google's and Uber's published LLM-assisted migration work shares one shape — a deterministic-plus-LLM inventory phase that catalogs dependencies, side effects, and implicit contracts before any code changes.

Tier: Core · Workflow area: Refactoring & Migration

An agent can build that inventory in hours instead of weeks; your job is to force it to cite evidence and to sign off on the resulting charter.

When to use

  • A framework/library upgrade, service extraction, or rewrite touching a module nobody fully understands anymore.
  • Onboarding to ownership of a legacy module ("you own billing now").
  • Before estimating any migration — an inventory turns a guess into a scoped plan.

Skip for modules with current docs, high test coverage, and a living owner — just read the docs.

Prerequisites

  • Repo access with an agentic tool that can explore (Claude Code, Copilot agent mode, Cursor) — read-only is fine and safer.
  • Deterministic extractors for ground truth: dependency graphs (pydeps, madge, jdeps), coverage report if tests exist, and grep.
  • The migration's actual goal in one sentence (upgrade Django 3→5? extract to a service? retire?) — the charter's shape depends on it.

The workflow

  1. Pull deterministic facts first.

    madge --json src/legacy/orders > /tmp/deps.json          # who orders/ imports
    madge --json src | jq 'to_entries[] | select(.value[] | contains("legacy/orders"))' # who imports orders/
    grep -rn "os.environ\|settings\." src/legacy/orders | sort > /tmp/config-reads.txt
    

    Tool-extracted graphs are the skeleton the LLM must hang claims on — never let the model be the source of the dependency list, only its interpreter.

  2. Run the agentic exploration with an evidence rule.

    Explore src/legacy/orders (read-only). Build an inventory with these
    sections; every claim must cite file:line, and unverifiable claims must be
    marked ASSUMPTION:
    
    1. Entry points: every route/handler/job/CLI/signal that invokes this module
    2. Outbound side effects: DB writes (which tables), network calls, file I/O,
       queue publishes, emails, global/state mutation
    3. Implicit contracts: behaviors depended on but not in any interface —
       ordering guarantees, exception types callers catch, dict shapes, magic
       values, timezone/locale assumptions
    4. Config & environment: every env var, setting, and feature flag read
    5. Data ownership: tables/collections this module is the sole writer for,
       vs shared with [list from deps.json]
    6. Test reality: what existing tests actually pin vs what is untested
    7. Surprises: anything that contradicts the module's apparent purpose
    

    Section 3 is the one that saves you: implicit contracts are what break in migrations, and they are exactly what no documentation mentions.

  3. Audit the inventory against the deterministic facts. Cross-check the agent's entry-point and dependency claims against deps.json and your grep output. Spot-check 5 random file:line citations — do they say what is claimed? Follow every ASSUMPTION tag: each becomes either a verified fact (you checked) or an open risk (into the charter). An inventory that survives this audit is trustworthy enough to plan on.

  4. Probe the scariest implicit contracts. For the top 3–5 implicit contracts, get evidence beyond reading:

    You claimed callers depend on process_batch() returning items in insertion
    order (orders/batch.py:112 cited). Write a minimal script/test that proves
    or disproves: (a) the function guarantees this today, (b) at least one
    caller breaks if order changes.
    

    Run it. Contracts proven by executing code go into the charter as constraints; the rest stay risks.

  5. Draft the migration charter. From the audited inventory, have the model draft — then you edit — a one-to-two-page charter: scope (in/out), the invariant list (implicit contracts that must survive, each with its evidence link), risk register with mitigations (usually: characterization tests — see pb-22), sequencing (strangle order, see pb-25 if extracting), and explicit no-go conditions ("if the shared-table write in section 5 can't be isolated, stop and re-plan"). Circulate to the two longest-tenured engineers for a "what did we miss" pass — tribal knowledge still beats any agent.

Key Takeaway:

The deliverable is not understanding in your head — it is a cited, audited inventory plus a charter that a teammate could execute. If the inventory can't say who calls the module and what breaks when behavior changes, you are not ready to migrate.

Tool variants

  • Claude Code: strongest exploration depth; use plan mode / read-only permissions for the inventory phase so exploration cannot mutate anything; CLAUDE.md can carry the evidence-rule so every future exploration inherits it.
  • Copilot agent mode / Cursor: same prompt works; for very large modules, run section-by-section (entry points, then side effects...) to stay within context.
  • Deterministic core, any-LLM shell: madge/pydeps/jdeps + coverage + grep produce the skeleton; even a modest model can interpret and organize on top of solid extracted facts.

Verification

  • 5-of-5 random citation spot-checks pass (file:line exists and supports the claim).
  • Agent's dependency claims reconcile with the tool-generated graph — discrepancies investigated, not ignored.
  • Every ASSUMPTION resolved to verified-fact or logged-risk; zero silent assumptions remain.
  • Top implicit contracts have executable evidence (a probe script or test), not just a citation.
  • Two senior engineers reviewed the charter and their corrections were incorporated.

Pitfalls

  • Letting the agent narrate instead of cite. Uncited inventories read beautifully and contain confident fiction. The evidence rule is non-negotiable.
  • Inventorying the code but not the data. Sole-writer vs shared tables (section 5) decides whether extraction is even possible; models under-weight data coupling because it is less visible in code.
  • Skipping the human pass. The agent cannot know that "the Tuesday job must run before the batch or Finance's numbers are wrong" if it is written nowhere. Tribal-knowledge review catches exactly this.
  • Charter sprawl. A 15-page charter is a document nobody maintains. One-to-two pages, evidence linked not inlined.

Restricted-environment variant

  • Client-repo restrictionsrun the deterministic extractors (all local) and do the LLM organization step over the extracted artifacts (dependency JSON, grep output, signatures) rather than raw source — often acceptable under policies that prohibit sharing implementation code; confirm first.
  • Local-model routeOllama + a coder model handles inventory organization and section drafting over extracted facts; comprehension of raw legacy source is weaker — compensate with more deterministic extraction and human reading of the flagged hotspots.
  • Model-free fallbackthe charter format, evidence rule, and probe-script discipline are model-free practices; they work verbatim in a no-AI environment, just slower.

Success criteria

  • A module that was "nobody knows" is now a cited inventory + charter produced in days, not weeks.
  • Mid-migration surprises drop to near zero for charter-covered scope — surprises that do occur trace to a section you skipped, which is the lesson.
  • The inventory is reusable: the next engineer starts from your artifact instead of from git log archaeology.
This is the free reading view. Open BXUP to track your progress, run the hands-on labs, and prove it with original, exam-pattern assessments.
© Anvi Innovate · BXUP — Be Exponentially Upskilled · BXUP is an independent learning platform, not affiliated with or endorsed by AWS, Microsoft, Google, NVIDIA, IBM, Salesforce, Databricks, Oracle or Anthropic. All trademarks belong to their respective owners. · bxup.in