Exercises: Migrating Legacy Pipelines

Solutions and grading notes are in the instructor companion. Exercises marked ๐Ÿงช use code/migration_lab.py.


Warm-Up

Exercise 37.1 โ€” What makes it hard

Difficulty: โ˜…โ˜†โ˜† ยท Time: 15 minutes

ยง37.1 names four things, none of them the rewrite: nobody knows what it does ยท nobody knows who uses it ยท the old system is wrong in ways people have adapted to ยท there is no feature to point at.

  1. For a legacy job you know, score each of the four: yes, no, or unknown.
  2. Which of the four is worst in your case?
  3. ยง37.1 says the technical work is usually the easy part. Estimate the rewrite in days, then estimate the other four. Compare.

Exercise 37.2 โ€” Take the inventory

Difficulty: โ˜…โ˜†โ˜† ยท Time: 45 minutes

ยง37.2's eight fields, all discoverable without reading code.

  1. Inventory five legacy jobs you have access to. Fill in every field.
  2. How many have an owner? Tests? Kestrel: 2 of 12 and 1 of 12.
  3. Count the undocumented dependencies โ€” inputs not named in any config. You find these by running it.
  4. How long did the inventory take? Kestrel's twelve took three weeks.

Exercise 37.3 โ€” Read the ordering

Difficulty: โ˜…โ˜†โ˜† ยท Time: 20 minutes ยท ๐Ÿงช

python code/migration_lab.py --inventory
  1. The first job is neither the highest-reach nor the easiest. Name both, and say why neither is first.
  2. informatica_wf_inventory scores risk 25 with zero lines of code. Where does the risk come from?
  3. hourly_stock_sync.py scores 2.6. What is different about it, and what does ยง37.12 conclude?
  4. Change the formula to reach ร— risk (drop the difficulty divisor). How does the order change, and is it better?

Core

Exercise 37.4 โ€” Find your consumers

Difficulty: โ˜…โ˜…โ˜† ยท Time: 60 minutes

ยง37.2's four methods, and Case Study 2's finding that three of them share a blind spot.

  1. Run the first three methods on one output you own. Record what each finds.
  2. ยง"Failure Mode" says instrumentation finds systems and misses people. How many of your consumers are a person opening a file?
  3. Compute the probability that a week of access monitoring sees a monthly consumer. Kestrel: 23%.
  4. Design the fourth method for your organization โ€” announced, bounded, reversible โ€” and list the safeguards. Case Study 2 has seven.
  5. Would you actually run it? If not, what is the honest alternative?

Exercise 37.5 โ€” Score and order your estate

Difficulty: โ˜…โ˜…โ˜† ยท Time: 45 minutes ยท ๐Ÿงช

  1. Put your Exercise 37.2 inventory into LEGACY's format and run --inventory.
  2. Which job does it recommend first? Does that surprise you?
  3. Argue for a different first job. What does your argument optimize for โ€” size, ease, politics, or learning?
  4. ยง37.4's weights are a judgment. Change one and see whether the order moves. If it does not, the weight is not doing anything.

Exercise 37.6 โ€” Write the reconciliation

Difficulty: โ˜…โ˜…โ˜† ยท Time: 45 minutes

ยง37.6: grain, tolerance, window โ€” decided before the first comparison.

  1. For one job: what is the natural key you will reconcile on?
  2. What tolerance, as a number, and for which columns? Zero is the right default for counts and integer money.
  3. Write the FULL OUTER JOIN. Explain why an inner join is not sufficient in one sentence.
  4. Add the monthly comparison that the daily one would miss.

Exercise 37.7 โ€” Classify the differences

Difficulty: โ˜…โ˜…โ˜† ยท Time: 45 minutes ยท ๐Ÿงช

python code/migration_lab.py --shadow
  1. Six kinds, 687 differences. Which are irreducible, and what share? (Kestrel: 50.2%.)
  2. 196 legacy bugs against 146 new ones. Explain why that ratio is not surprising, in terms of Chapter 23.
  3. Differences fall from 238 in week one to 17 in the last week. What would it mean if they did not fall?
  4. Write your own classification scheme. Does every kind have a verdict attached? A kind without a verdict is a kind that will be argued about each time.

Exercise 37.8 โ€” Decide in advance

Difficulty: โ˜…โ˜…โ˜† ยท Time: 40 minutes

ยง37.7: what happens when the legacy system is the one that is wrong.

  1. Write your organization's policy, before you need it. Kestrel's has three clauses.
  2. Set the materiality threshold as a number. What is it, and who set it?
  3. Argue for bug-for-bug compatibility as a default, then against it. Which do you believe?
  4. Design the two-column output (Case Study 1). Where does the removal date live?

Exercise 37.9 โ€” The readiness rule

Difficulty: โ˜…โ˜…โ˜† ยท Time: 30 minutes ยท ๐Ÿงช

python code/migration_lab.py --ready
  1. Kestrel scores 14/17, blocked by the rehearsed rollback. Write your own rule, with weights.
  2. ยง37.9 says a rule requiring zero differences never fires. Why?
  3. Rehearse a rollback for something you own. Time it. Compare against what your plan claims.
  4. Kestrel's rehearsal found three things a written plan did not. What did yours find?

Exercise 37.10 โ€” Price the overlap

Difficulty: โ˜…โ˜…โ˜† ยท Time: 40 minutes ยท ๐Ÿงช

python code/migration_lab.py --cost
  1. Run it with your numbers: two pipelines' daily cost, and engineer-days per month of triage.
  2. ยง37.10 says the engineering line exceeds the compute line. Is that true for you?
  3. Kestrel's overlap ran 2.45ร— the plan, almost entirely waiting for business decisions. What is your multiplier, and what drives it?
  4. Compute the payback on the overrun. If it exceeds a year, what is your actual justification for the migration?

Advanced

Exercise 37.11 โ€” Extend the lab

Difficulty: โ˜…โ˜…โ˜… ยท Time: 90 minutes ยท ๐Ÿงช

Add three to migration_lab.py, with self-checks:

  1. A dependency graph between legacy jobs, so the ordering respects "B reads A's output."
  2. A per-job shadow simulation with its own decay rate, so you can predict a cutover date.
  3. A decommission tracker (ยง37.11) with dates and owners, failing on an overdue ticket.
  4. A "consumers found by method" model (Case Study 2), including the periodicity effect.
  5. A sensitivity analysis on the ordering weights: which job moves most when a weight changes?
  6. A two-column-removal deadline check โ€” a migration is not done while both columns exist.

Then: run #5. If the order is insensitive to every weight, the score is not doing anything โ€” say what that would mean.


Exercise 37.12 โ€” Migrate a GUI workflow you cannot open

Difficulty: โ˜…โ˜…โ˜… ยท Time: 90 minutes

ยง37.8's three approaches: read the generated SQL, treat it as a black box, or ask the business.

  1. Pick a system whose logic you cannot read โ€” a GUI tool, a vendor process, a binary.
  2. Try the first approach. Does it log its SQL, its API calls, or its queries?
  3. Design the black-box approach. What input space would you have to exercise, and how would you know you had covered it?
  4. Write the three questions you would ask the business. ยง37.8's rebuild was 40% smaller because the requirement was smaller than the implementation.
  5. ยง37.8's question is "what is this for, and is that still true?" โ€” ask it of five things you maintain.

Exercise 37.13 โ€” The load-bearing spreadsheet

Difficulty: โ˜…โ˜…โ˜… ยท Time: 60 minutes

ยง37.3's โš ๏ธ callout: separate the rules from the decisions, migrate only the rules.

  1. Find one. Every organization has at least one spreadsheet in a production path.
  2. Classify every formula and every manual step as a rule or a judgment.
  3. Design the versioned input table the judgments become. What fields does it need besides the value?
  4. ยง37.3 says a surviving manual step is the correct home for a decision. Argue against that, then say what your alternative costs.
  5. Who is the owner, and have you told them they are the asset rather than the blocker?

Exercise 37.14 โ€” Decide what not to migrate

Difficulty: โ˜…โ˜…โ˜… ยท Time: 45 minutes

ยง37.12: Kestrel rebuilt 8, deleted 2, absorbed 1, and left 1 alone.

  1. For each job in your inventory, choose: rebuild, delete, absorb, or leave alone.
  2. Apply ยง37.12's test to each: what specifically will we be able to do afterwards that we cannot do now?
  3. How many can you delete? Kestrel deleted two of twelve, found by asking what the output was for.
  4. ยง37.12 says "legacy" is not a synonym for "old." Which of your jobs is old and not legacy?
  5. Write down the decision for each, including the ones you are not migrating โ€” an undocumented non-decision looks like an oversight.

Project Milestone

Exercise 37.15 โ€” Migrate one job end to end

Difficulty: โ˜…โ˜…โ˜… ยท Time: 4โ€“6 hours ยท ๐Ÿงช

Take one real legacy job โ€” yours, or a deliberately crude script you write first โ€” through the whole sequence.

  1. Inventory it (ยง37.2), all eight fields, without reading the code.
  2. Find its consumers with at least three methods, and record what each found.
  3. Score it and place it in an order against at least four others.
  4. Rebuild it, with tests and an owner.
  5. Shadow-run and reconcile, with a FULL OUTER JOIN, for at least ten cycles.
  6. Classify every difference, and record each in a ledger with a verdict and a date.
  7. Write the readiness rule and score against it, including rehearsing the rollback and timing it.
  8. Cut over, leave the legacy job running unread for one cycle, then delete it โ€” the job, the code, the credentials, and the infrastructure.
  9. Price the whole thing, including your own time.

Deliverable: the inventory, the consumer census with its methods, the difference ledger, the readiness score, the timed rollback rehearsal, the decommission record, and the cost.

The difference ledger is the artifact that matters. If it is empty, either your rebuild is suspiciously perfect or your reconciliation is not comparing what you think it is โ€” and ยง37.7 says the second is far more likely.