# 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.

```
To change five-year-old code:
  1. read it to work out what it does        (days)
  2. guess why it was built this way         (no documentation)
  3. check what breaks when you change it    (no tests)
  4. eventually: "let's leave it"            ← most stop here
```

Legacy was what you left alone because **the cost of fixing exceeded the cost of
leaving it.**

## The arithmetic collapses

When [code is derived](/guide/ha-intentops), that arithmetic changes.

```
Instead of struggling to understand the old part
→ rebuild it from the intent
```

When understanding costs more than regenerating, **not understanding and
rebuilding is the rational move.**

```mermaid
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.**

```
Old technical debt:  hard-to-read code, duplication, tangled dependencies
New technical debt:  areas with thin test coverage
```

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.

```
Behaviour depended on but never tested:
  - a certain field was always present in the response
  - sorting was always in the same order
  - the error message had specific wording
```

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?**

<details>
<summary>Answer</summary>

**Old code nobody dares touch.** The cost of understanding it — reading it,
guessing why, checking what breaks — exceeded the cost of leaving it alone.
</details>

**2. What does technical debt become under fluid software?**

<details>
<summary>Answer</summary>

**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.
</details>

**3. What must you watch most carefully when regenerating?**

<details>
<summary>Answer</summary>

**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.
</details>

---

That is the three concepts. Now into the actual process →
[Map of the four processes](/guide/ha-process-overview)
