# IntentOps

> **What you will learn**
> What "you produce intent, not code" actually means, and the two things a
> developer owns.

## The output changes

Until now a developer's output was **code.** Under IntentOps:

| | Output | What is reviewed |
|---|---|---|
| Before | code | code review |
| **IntentOps** | **intent + tests** | **is the intent right, are the tests sufficient** |

AI handles implementation. The developer defines **what to build and how we know
it is done.**

## The two things you own

### 1. The specification — unambiguous

Write it in plain language, but **leave no room for interpretation.**

```
✗ "Let people apply coupons in the cart"

✓ "Enter a coupon code in the cart to apply a discount.
   - Only one coupon applies (no stacking)
   - Expired coupons show 'This coupon has expired'
   - Below the minimum order value, show 'Valid on orders over $30'
   - The total updates immediately after applying"
```

**Room for interpretation is a bug.** In the example above, omit "no stacking"
and AI decides for itself — and that decision may differ from what was intended.

This is [the four parts of a good instruction](/guide/ai-intent-context) applied
to code work.

### 2. The tests — an executable pass criterion

The specification turned into **something judgeable.**

```
Tests:
  1. Apply a valid coupon → discounted price shown
  2. Try to apply a second coupon → rejected + message
  3. Expired coupon → 'This coupon has expired'
  4. $30 coupon on a $20 order → 'Valid on orders over $30'
  5. After applying, total = original − discount
```

> **Tests are the only definition of "done."** Five pass, it is finished; they do
> not, it is not. There is no "almost there."

## Code is ephemeral

This is where the well-known phrase comes from — **"code is ephemeral."**

When you need to optimise or move to a different stack, **you do not edit the
code; you regenerate it from the same intent.**

```mermaid
graph TD
  I["Intent + tests<br/>the original"] --> C1["Code v1"]
  I --> C2["Code v2<br/>performance pass"]
  I --> C3["Code v3<br/>different language"]
  C1 -.->|"all pass the same tests"| T["Pass criterion"]
  C2 -.-> T
  C3 -.-> T
```

**Intent and tests are the original; code is derived.** The old way inverted this
— code was the original and documentation was derived, which is why the
documentation was always behind.

## What gets harder

Honestly, **some things get harder.**

| | Before | IntentOps |
|---|---|---|
| Starting vaguely | possible (figure it out while building) | **impossible** |
| Understanding by building | a common approach | you must understand up front |
| Partial completion | "we're 80% there" | pass or not pass |

**"Build it and understand the requirements as you go" stops working.** That was
a genuinely common approach, so it takes adjustment.

But **splitting small mitigates it.** One micro-sprint is small enough to
understand from the outset. The difficulty comes from trying to specify a large
feature in one go.

## How to start in practice

Before adopting it wholesale, practise like this:

```
1. Pick one task (a small one)
2. Write the tests before writing any code
3. Check whether those tests can judge "done"
4. If not, the specification is incomplete → rewrite it
```

**Getting stuck at step 3 is the important experience.** Most people first
discover "these cannot judge completion." That shows how vaguely they had been
starting all along.

## Common misconceptions

### "Isn't this just TDD?"

Similar but different.

| | TDD | IntentOps |
|---|---|---|
| Tests first | yes | yes |
| A person writes the code | **yes** | no |
| Status of code | an asset | **derived** |
| Purpose | better design | **automating the judgement of done** |

If you have TDD habits, moving to IntentOps is easy.

### "Doesn't writing specs that detailed take longer than writing the code?"

**It might, once.** But the specification gets reused — when regenerating, when
building something similar, and when checking later why it was built this way.

Code, once written, is the end of that code. Intent stays alive.

---

## Check yourself

**1. What two things does a developer own under IntentOps?**

<details>
<summary>Answer</summary>

**The specification (unambiguous) and the tests (an executable pass criterion).**
AI handles implementation.
</details>

**2. What has to be true for "code is ephemeral" to hold?**

<details>
<summary>Answer</summary>

**The tests must be dense enough.** Tests are the only thing guaranteeing that
regenerated code preserves the old behaviour, so with weak tests regeneration is
a gamble rather than an improvement.
</details>

**3. What gets harder under IntentOps?**

<details>
<summary>Answer</summary>

**Starting vaguely becomes impossible.** "Build it and understand the
requirements as you go" stops working. Splitting work small mitigates it.
</details>

---

When code becomes derived, the definition of legacy changes too →
[Fluid software](/guide/ha-fluid-software)
