Fluid software
What you will learn What legacy becomes once code is derived, and what you must protect instead.
What legacy used to mean
Until now legacy meant this:
Old code nobody dares touch.
Why was it frightening? Because of the cost of understanding it.
Legacy was what you left alone because the cost of fixing exceeded the cost of leaving it.
The arithmetic collapses
When code is derived, that arithmetic changes.
When understanding costs more than regenerating, not understanding and rebuilding is the rational move.
graph TD
A["Old part found"] --> B{"Do intent and tests exist?"}
B -->|"yes"| C["Regenerate from the same intent"]
B -->|"no"| D["Read and fix it the old way"]
C --> E["Confirm identical behaviour via tests"]The branch is "do intent and tests exist?" Without them, fluid software does not hold.
What you must protect moves
| Before | Fluid software | |
|---|---|---|
| The asset | code | specification + tests |
| What to back up | the repository | the repository (the intent lives there) |
| What is reviewed | code changes | intent changes |
| Technical debt | bad code | thin tests |
The last row matters. The definition of technical debt changes.
Where tests are thin, that area cannot be regenerated — there is no way to confirm the regeneration is correct. So that area alone calcifies the old way.
How far this really goes
Honestly, few organisations regenerate everything. The realistic picture:
| Area | Reality |
|---|---|
| New features | start with intent + tests. Regenerable |
| Code from the last 1–2 years | partially regenerable if tests exist |
| Old core logic | leave it alone. Do not touch |
| External integrations | contracts are fixed, so little room to regenerate |
Starting with new work is the realistic entry point. Try to convert all existing code and you never start.
What gets better
1. Stack migration gets easier
When you have to change language or framework, intent and tests let you rebuild. That used to be a multi-month project.
2. Optimisation gets easier
"Same behaviour, better performance" becomes unambiguous. Tests pin the behaviour, so you can change anything within them.
3. Code review gets shorter
Review moves to intent. Instead of reading implementation line by line, you ask "is this intent right, are the tests sufficient?"
What to watch out for
Tests are the specification
Behaviour not written in the tests is not guaranteed. It can disappear on regeneration.
These implicit contracts break after regeneration. So in practice, before regenerating, you check "what does everything else assume about this area?"
Regeneration is not always the answer
For a small change, just fixing it is faster. Regeneration is a tool for areas that have aged into being hard to understand.
Check yourself
1. What was the old definition of legacy and why did it come about?
Answer
Old code nobody dares touch. The cost of understanding it — reading it, guessing why, checking what breaks — exceeded the cost of leaving it alone.
2. What does technical debt become under fluid software?
Answer
Areas with thin test coverage. Without tests there is no way to confirm a regeneration is correct, so that area alone calcifies the old way.
3. What must you watch most carefully when regenerating?
Answer
Implicit contracts not written in the tests. Response field presence, sort order, error wording — behaviour others depend on but which no test covers can break after regeneration.
That is the three concepts. Now into the actual process → Map of the four processes