# IntentOps

> **이 장에서 배우는 것**
> "코드가 아니라 의도를 만든다"가 실제로 무슨 뜻인지, 그리고 개발자가 책임지는
> 두 가지.

## 산출물이 바뀝니다

지금까지 개발자의 산출물은 **코드**였습니다. IntentOps에서는 이렇게 바뀝니다.

| | 산출물 | 검토 대상 |
|---|---|---|
| 기존 | 코드 | 코드 리뷰 |
| **IntentOps** | **의도 + 테스트** | **의도가 맞는지, 테스트가 충분한지** |

구현은 AI가 맡습니다. 개발자는 **무엇을 만들지와 됐다는 걸 어떻게 아는지**를
정의합니다.

## 책임지는 두 가지

### 1. 명세 — 모호하지 않게

자연어로 쓰되 **해석의 여지를 남기지 않습니다.**

```
✗ "장바구니에 쿠폰을 적용할 수 있게"

✓ "장바구니에 쿠폰 코드를 입력해 할인을 적용한다.
   - 쿠폰은 하나만 적용된다 (중복 불가)
   - 만료된 쿠폰은 '사용 기한이 지난 쿠폰입니다' 표시
   - 최소 주문 금액 미달 시 '3만원 이상 주문 시 사용 가능' 표시
   - 적용 후 총액이 즉시 갱신된다"
```

**해석의 여지가 곧 버그입니다.** 위 예에서 "중복 불가"를 안 적으면 AI가 알아서
정하고, 그 결정이 기획 의도와 다를 수 있습니다.

이건 [좋은 지시의 네 요소](/guide/ai-intent-context)를 코드 작업에 적용한
것입니다.

### 2. 테스트 — 실행 가능한 합격 기준

명세를 **판정 가능한 형태**로 만든 것입니다.

```
테스트:
  1. 유효한 쿠폰 적용 → 할인가 표시
  2. 두 번째 쿠폰 적용 시도 → 거부 + 안내 문구
  3. 만료 쿠폰 → '사용 기한이 지난 쿠폰입니다'
  4. 2만원 주문에 3만원 쿠폰 → '3만원 이상 주문 시 사용 가능'
  5. 적용 후 총액 = 원가 - 할인액
```

> **테스트가 "완료"의 유일한 정의입니다.** 다섯 개가 통과하면 끝난 것이고,
> 통과 안 하면 안 끝난 것입니다. "거의 다 됐다"가 없습니다.

## 코드는 일시적입니다

여기서 유명한 표현이 나옵니다 — **"code is ephemeral"**.

최적화가 필요하거나 다른 스택으로 옮겨야 하면, **코드를 고치는 게 아니라 같은
의도로 다시 생성합니다.**

```mermaid
graph TD
  I["의도 + 테스트<br/>원본"] --> C1["코드 v1"]
  I --> C2["코드 v2<br/>성능 개선판"]
  I --> C3["코드 v3<br/>다른 언어"]
  C1 -.->|"전부 같은 테스트를 통과"| T["합격 기준"]
  C2 -.-> T
  C3 -.-> T
```

**의도와 테스트가 원본이고 코드는 파생물입니다.** 이 관계가 뒤집힌 게 기존
방식이었습니다 — 코드가 원본이고 문서가 파생물이라 문서가 항상 뒤처졌습니다.

## 무엇이 어려워지나

솔직하게 말하면 **더 어려워지는 부분이 있습니다.**

| | 기존 | IntentOps |
|---|---|---|
| 애매하게 시작하기 | 가능 (만들면서 정함) | **불가능** |
| 만들면서 이해하기 | 흔한 방식 | 앞에서 이해해야 함 |
| 부분 완료 | "80% 됐어요" | 통과 아니면 미통과 |

**"일단 만들어보면서 요구사항을 이해하는" 방식이 안 통합니다.** 이건 실제로
많이 쓰이던 방식이라 적응이 필요합니다.

다만 **작게 나누면 완화됩니다.** 마이크로 스프린트 하나는 애초에 이해하기 쉬운
크기입니다. 큰 기능을 한 번에 명세하려니 어려운 것입니다.

## 실무에서 시작하는 법

전면 도입 전에 이렇게 연습할 수 있습니다.

```
1. 작업 하나를 고른다 (작은 것)
2. 코드를 쓰기 전에 테스트를 먼저 적는다
3. 그 테스트가 "완료"를 판정할 수 있는지 확인한다
4. 못 하면 명세가 부족한 것 → 다시 적는다
```

**3번에서 막히는 경험이 중요합니다.** 대부분 처음에는 "이걸로는 완료를 판정할 수
없다"는 걸 발견합니다. 그게 지금까지 얼마나 애매하게 시작했는지를 보여줍니다.

## 자주 하는 오해

### "TDD랑 같은 거 아닌가?"

비슷하지만 다릅니다.

| | TDD | IntentOps |
|---|---|---|
| 테스트를 먼저 | 예 | 예 |
| 코드를 사람이 씀 | **예** | 아니오 |
| 코드의 지위 | 자산 | **파생물** |
| 목적 | 설계 개선 | **완료 판정 자동화** |

TDD의 습관이 있으면 IntentOps로 넘어가기 쉽습니다.

### "명세를 그렇게 자세히 쓰면 코드 쓰는 것보다 오래 걸리지 않나?"

**한 번은 그럴 수 있습니다.** 그런데 그 명세는 재사용됩니다 — 재생성할 때,
비슷한 기능을 만들 때, 나중에 왜 이렇게 만들었는지 확인할 때.

코드는 한 번 쓰면 그 코드로 끝이지만, 의도는 계속 살아 있습니다.

---

## 확인

**1. IntentOps에서 개발자가 책임지는 두 가지는?**

<details>
<summary>답</summary>

**명세(모호하지 않게)와 테스트(실행 가능한 합격 기준)**입니다. 구현은 AI가
맡습니다.
</details>

**2. "코드는 일시적"이라는 말이 성립하려면 무엇이 전제되어야 합니까?**

<details>
<summary>답</summary>

**테스트가 충분히 촘촘해야 합니다.** 재생성한 코드가 예전 동작을 유지하는지
보장하는 게 테스트뿐이므로, 테스트가 부실하면 재생성은 개선이 아니라 도박이
됩니다.
</details>

**3. IntentOps에서 무엇이 더 어려워집니까?**

<details>
<summary>답</summary>

**애매하게 시작하는 것이 불가능해집니다.** "일단 만들면서 요구사항을 이해하는"
방식이 안 통합니다. 다만 작업을 작게 나누면 완화됩니다.
</details>

---

코드가 파생물이 되면 레거시의 정의도 바뀝니다 →
[유동적 소프트웨어](/guide/ha-fluid-software)
