> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nora.my/llms.txt
> Use this file to discover all available pages before exploring further.

# 개선과 버전

> 개선 큐를 제품 안에 심기 : fix 제시, 사람 승인, 버전 배포

**개선(improvement)은 군집(cluster)이 아닙니다.** 군집은 묶인 실패들이고, 개선은 **그 군집 하나를 겨냥한 구체적 수정 제안**입니다. title, `before → after` diff, 시뮬레이션으로 측정된 delta를 함께 들고 옵니다. 루프가 이걸 만들고 재어 보며, SDK는 **제품 안에서 큐를 보여 주고 사람이 결정** 하게 하는 자리입니다.

이걸 제품에 심는 이유는 명확합니다. 고객이 Nora 대시보드로 건너오지 않고 자기 관리자 페이지에서 승인합니다. 단일 승인 게이트는 그대로(사람이 누름), 감사에는 행위자만 바뀌어 남습니다.

훑는 데엔 **PAT `read`**, 결정에는 \*\*PAT `approve`\*\*가 필요합니다.

## `Improvement` 모양

`improvements.list` / `improvements.get`이 돌려주는 것:

* `id`, `kind`, `title`, `status`
* `addresses` 이 개선이 고치는 실패 수
* `delta` 시뮬 개선 폭 (아직 측정 전이면 `null`)
* `clusterKey` 대상 군집
* `graphSlug` 개선이 적용될 Flow slug (워크스페이스 스코프 fix는 `null`)
* `targetAgentId` / `targetAgentName` 고칠 에이전트
* `diagnosis` 왜 (루프의 분류기가 판정한 이유)
* `proposal` 주 `before → after` (`changes[0]` 미러)
* `changes[]` 전체 typed 변경셋 `{ surface, target, before, after, rationale }`
* `compare` 2축 시뮬 결과 (before vs after)

## 훑기

```ts theme={null}
const queue = await nora.improvements.list("proposed");  // status 필터, read 스코프
const one   = await nora.improvements.get("imp_1");       // 상세: diagnosis · changes · compare
```

status 값: `proposed`(결정 대기), `approved`(채택 → 배포됨), `rejected`(기각됨), `reverted`(배포된 fix가 `revert`로 되돌려짐). 서버가 새 상태를 추가할 수 있으니 확장 가능한 문자열로 다루세요.

## 결정

```ts theme={null}
await nora.improvements.approve("imp_1");                     // 채택 → 새 버전 배포
await nora.improvements.approve("imp_2", { edits: [0, 2] }); // changes[] 중 이 항목만 채택
await nora.improvements.reject("imp_3");                      // 기각 (보조)
```

\*\*요점은 `approve`\*\*입니다. 여기서 사람이 결정합니다. `reject`는 보조입니다(미승인 제안은 어차피 배포되지 않으므로). `approve`는 **`approve`** 스코프를 요구하고, `reject`는 `read`로도 됩니다.

`approve({ edits })`는 여러 `surface`에 걸친 `changes[]` 배열에서 일부 항목만 채택하게 합니다. 예를 들어 프롬프트 변경은 받되 툴 설정 변경은 건너뜁니다. 인덱스는 `changes` 배열 순서를 따릅니다.

## 안전 밸브

```ts theme={null}
await nora.improvements.revert("imp_1");         // 배포된 fix 되돌리기
const stale = await nora.improvements.staleFixes(); // 배포 후 효과가 부식된 fix, 재실험 후보
```

`revert`는 배포 후 undo라 `approve` 스코프가 필요합니다(프로덕션을 바꾸므로). `staleFixes`는 측정 효과가 시간이 지나 부식된(밑바탕 실패 패턴이 다시 나타난) fix들을 돌려줍니다. 재시뮬레이션 큐에 올릴 후보입니다.

## `versions`

같은 DAG지만 층위가 다릅니다. `versions`는 Flow 버전 포인터를 직접 다룹니다. 개선은 버전으로 배포되지만, 개선 큐를 거치지 않고 포인터만 움직일 수도 있습니다.

```ts theme={null}
const vers = await nora.versions.list();       // 무엇이 언제 배포됐나, 저자와 개선 참조 포함
await nora.versions.rollback("ver_9");         // 게시 포인터 되돌리기, approve 스코프
```

개선 `revert`보다 빨리 포인터가 움직여야 할 때(예: 개선과 무관한 잘못된 게시) `versions.rollback`을 씁니다.

## `simulate` · `generate`는 왜 여기 없나

개선 큐는 루프의 출력이 떨어지는 자리입니다. 개선을 **만드는** 것(실패 분류기 실행, 후보 생성, 시뮬 측정)은 루프의 내부가 하는 일이지 SDK가 할 일이 아닙니다. SDK는 결정을 내리는 자리지 생성기가 아닙니다.

on-demand로 근거를 만들고 싶으면(예: 특정 fix를 다시 시뮬레이션), 그건 [`simulations`](https://docs.nora.my/ko/sdk/simulations)입니다. `promote(roundId)` verb가 시뮬 결과를 개선 제안으로 등록해, 이 큐로 흘러 들어와 승인을 받게 합니다.

## 흔한 패턴

### 제품에 심은 승인

관리자 UI에 대기 중인 개선을 표시:

```ts theme={null}
const queue = await nora.improvements.list("proposed");

render(queue.map((imp) => ({
  title: imp.title,
  agent: imp.targetAgentName,
  fixes: imp.addresses,               // "N 개 실패 수정"
  delta: imp.delta,                    // "+12% 정확도"
  diff: imp.proposal,                  // {before, after}
  onApprove: () => nora.improvements.approve(imp.id),
  onReject:  () => nora.improvements.reject(imp.id),
})));
```

감사 기록에는 **여러분 쪽 관리자 사용자**가 승인자로 남습니다. 같은 게이트, 다른 위치입니다.

### 여러 `surface`에 걸친 변경 중 일부만 채택

개선은 흔히 여러 `surface`를 건드립니다(프롬프트 + 툴 정책 + 데이터 소스 필터). 안전한 부분집합만 채택:

```ts theme={null}
const imp = await nora.improvements.get("imp_1");
const safe = imp.changes
  .map((c, i) => ({ i, c }))
  .filter(({ c }) => c.surface === "prompt")     // 이번엔 프롬프트 변경만
  .map(({ i }) => i);

await nora.improvements.approve("imp_1", { edits: safe });
```

### 부식 감시

주간:

```ts theme={null}
const stale = await nora.improvements.staleFixes();
if (stale.length) alertOncall({ staleFixes: stale });
```

그 뒤 fix를 재시뮬레이션하고([시뮬레이션](https://docs.nora.my/ko/sdk/simulations.md) 참고), 루프가 다시 promote할지 그대로 둘지 결정하게 합니다.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.