# master-succeed 레퍼런스

> detect·handoff·verify-successor·check-duplicates·retire·spawn 옵션, exit 코드, SPAWN_PLACEMENT_MISMATCH, JSON 출력.

- Repository: local/mogui-ADE-orchestrator

- Human docs: https://grok-wiki.com/public/docs/local-mogui-ade-orchestrator-97afe791d5ac
- Complete Markdown: https://grok-wiki.com/public/docs/local-mogui-ade-orchestrator-97afe791d5ac/llms-full.txt

## Source Files

- `scripts/master-succeed`
- `src/master_runtime/core/succession.py`
- `scripts/master-bootstrap`
- `scripts/master-bootstrap-live`
- `scripts/master-recover`
- `src/master_runtime/core/lineage.py`
- `tests/test_succession.py`
- `docs/public/reference.md`

---

---
title: "master-succeed 레퍼런스"
description: "detect·handoff·verify-successor·check-duplicates·retire·spawn 옵션, exit 코드, SPAWN_PLACEMENT_MISMATCH, JSON 출력."
---

`scripts/master-succeed`는 Orca 네이티브 마스터 승계(succession) CLI다. 구현은 `src/master_runtime/core/succession.py`의 `detect_trigger`, `build_handoff`, `verify_successor`, `detect_duplicate_instances`, `retire_predecessor`, `spawn_successor`에 위임한다. 성공 시 stdout에 JSON을 쓰고 exit `0`이다. 가드 위반은 `SuccessionError`로 stderr 메시지와 `exc.exit_code`를 반환한다(기본 `2`).

## 명령 요약

| 하위 명령 | 역할 | 핵심 입력 | 성공 시 payload 키 |
| --- | --- | --- | --- |
| `detect` | 승계 트리거 분류 | positional `text`, `--context-ratio` | `status`, `reason`, `message` |
| `handoff` | thin handoff 마크다운 생성 | `--spec` JSON 파일 | `handoff` |
| `verify-successor` | U8 recovery report 검증 | `--report` JSON 파일 | `status`, `checks`, `evidence` |
| `check-duplicates` | 동일 marker 중복 마스터 탐지 | `--self-handle`, `--marker` | `duplicates` |
| `retire` | predecessor 1개 해석·선택적 close | `--self-handle`, target 필드, `--execute` | `RetirementReport` 필드 |
| `spawn` | successor 터미널 create 또는 dry-run | workspace·kickoff·root·title·agent | `SpawnReport` 필드 |

공통 옵션:

- `--json` — 컴팩트 JSON(`separators=(",", ":")`, `sort_keys=True`). 생략 시 들여쓰기 JSON.
- `--fixture-json` — 숨김 테스트 훅. `orca terminal list` / scoped list / `close`를 fixture로 대체한다. 공개 운영 표면이 아니다.

```bash
scripts/master-succeed {detect|handoff|verify-successor|check-duplicates|retire|spawn} ...
```

## 공통 동작

- 파서는 `argparse` 서브커맨드 필수(`required=True`).
- stdout은 항상 JSON 객체(또는 배열 래핑 객체). 오류 본문은 stderr 문자열이며 JSON이 아니다.
- Orca 호출은 기본 `subprocess` 러너(`orca terminal list|create|close --json`). 단위 테스트는 `--fixture-json` 또는 인메모리 runner로 대체한다.
- 기본 에이전트 모델 맵(`scripts/master-succeed` `DEFAULT_MODELS`):

| `--agent` | 기본 `--model` |
| --- | --- |
| `claude`, `claude-code` | `claude-fable-5` |
| `grok`, `grok-build` | `grok-4.5` |
| `codex` | `gpt-5.6-sol` |
| 그 외(cursor/agy 포함, 미측정) | 기본 없음 → exit `2` (`--model is required for agent …`) |

## detect

```bash
scripts/master-succeed detect "succession now" --context-ratio 0.65 --json
```

### 옵션

<ParamField body="text" type="string" required>
승계 트리거로 분류할 원문. 소문자 normalize 후 부분 문자열 매칭.
</ParamField>

<ParamField body="--context-ratio" type="float">
컨텍스트 사용 비율. `>= 0.60`이면 명시 IMMEDIATE 마커가 없을 때 `ADVISORY`.
</ParamField>

<ParamField body="--json" type="boolean">
컴팩트 JSON 출력.
</ParamField>

### 판정 규칙

| `status` | 조건 | `reason` |
| --- | --- | --- |
| `IMMEDIATE` | 텍스트에 명시 마커 포함: `succession now`, `handoff to successor`, `승계해줘`, `다음 마스터로 넘기자`, `승계 진행해` | `explicit succession instruction` |
| `ADVISORY` | `context_ratio >= 0.60` | `context ratio threshold reached` + auto-succession 금지 메시지 |
| `ADVISORY` | context에 non-empty `milestone` (CLI는 ratio만 전달; 라이브러리 API용) | `natural milestone reached` |
| `NONE` | 그 외 | `no succession trigger` |

`IMMEDIATE`가 아니면 **자동 spawn하지 않는다**. advisory는 제안만 허용한다.

### JSON 출력

```json
{"message":"","reason":"explicit succession instruction","status":"IMMEDIATE"}
```

```json
{
  "message": "Context ratio is high. Auto-succession is not permitted; propose succession only.",
  "reason": "context ratio threshold reached",
  "status": "ADVISORY"
}
```

## handoff

```bash
scripts/master-succeed handoff --spec ./ops/handoff-spec.json --json
```

### 옵션

<ParamField body="--spec" type="path" required>
handoff 섹션을 채울 JSON 스펙 파일 경로.
</ParamField>

### 스펙 필드

| 키 | 용도 | 비고 |
| --- | --- | --- |
| `role_state` | Role State 동결 입력 | 없으면 `current_role` 또는 기본 `Reference Implementation`으로 `RoleState` 구성 |
| `current_role` | 현재 역할 | `role_state` 없을 때 사용 |
| `current_objective` | Current Objective | 텍스트 |
| `active_tracks` / `open_tracks` | Active/Open Tracks | 리스트 → `- item` 줄 |
| `accepted_artifacts` | Accepted Artifacts | 리스트 |
| `deferred_work` | Deferred Work | 리스트 |
| `open_questions` | Open Questions | 리스트 |
| `recommended_next_role` | Recommended Next Role | 기본: frozen current role |
| `observed_baseline` | Observed Baseline | 텍스트 |

출력 handoff는 Role State를 lock-enabled로 동결한다(`Frozen: all other roles`, `Unlock: explicit user instruction only`).

### JSON 출력

```json
{"handoff":"## Role State\n\n```\nCurrent Role: ...\n..."}
```

## verify-successor

```bash
scripts/master-succeed verify-successor --report ./ops/recovery-report.json --json
```

### 옵션

<ParamField body="--report" type="path" required>
U8 recovery report JSON. `steps` 배열에 `{ "step", "status" }` 항목.
</ParamField>

### 판정

| 결과 `status` | 조건 |
| --- | --- |
| `FAILED` | 어떤 step `status == "MISS"` |
| `PASS` | step `6` OK + `2-3` OK/없음 + `5` OK → checks 3개 |
| `PARTIAL` | checks 1–2개 |
| `FAILED` | checks 0개 |

checks 문자열:

- step `6` == `OK` → `open tracks recited`
- step `2-3` in (`OK`, 없음) → `baseline matched`
- step `5` == `OK` → `monitors rearmed`

### JSON 출력

```json
{
  "checks": ["open tracks recited", "baseline matched", "monitors rearmed"],
  "evidence": "checks=open tracks recited,baseline matched,monitors rearmed",
  "status": "PASS"
}
```

## check-duplicates

```bash
scripts/master-succeed check-duplicates \
  --self-handle <current-handle> \
  --marker <session-marker> \
  --json
```

### 옵션

<ParamField body="--self-handle" type="string" required>
현재 마스터 터미널 handle. 결과에서 제외한다.
</ParamField>

<ParamField body="--marker" type="string" required>
handle / pty / session / worktree / title / path 등 세션 필드 부분 문자열.
</ParamField>

동작:

1. `orca terminal list --json`으로 세션 수집
2. `handle != self_handle` 이고 marker가 매칭 필드에 부분 일치하면 중복 후보
3. 비어 있지 않은 `duplicates`는 **finding**이다. CLI는 그 자체로 non-zero exit를 강제하지 않는다(호출자가 해석).

### JSON 출력

```json
{
  "duplicates": [
    {
      "handle": "term-u8-shadow",
      "worktree_path": "...",
      "branch": "...",
      "title": "...",
      "connected": true,
      "pty_id": "...",
      "worktree_id": "...",
      "session_id": "...",
      "process_id": null
    }
  ]
}
```

`self_handle` 또는 marker가 비면 `SuccessionError` exit `2`.

## retire

```bash
scripts/master-succeed retire \
  --self-handle <successor-handle> \
  --target-handle <predecessor-handle> \
  --target-pid <pid> \
  --target-tty /dev/ttysNNN \
  --json
# 실제 close:
#   ... --execute
```

### 옵션

<ParamField body="--self-handle" type="string" required>
후임(또는 호출자) handle. 후보에 포함되면 self-close 거부로 raise.
</ParamField>

<ParamField body="--expected" type="string">
selector 모드 부분 문자열. exact target 필드가 없을 때 사용.
</ParamField>

<ParamField body="--target-handle" type="string">
predecessor handle 정확 일치.
</ParamField>

<ParamField body="--target-pty-id" type="string">
pty id 정확 일치.
</ParamField>

<ParamField body="--target-session-id" type="string">
session id 정확 일치.
</ParamField>

<ParamField body="--target-pid" type="integer">
외부 측정 pid. 터미널 레코드 `process_id`가 null인 folder-workspace 좌석에서 필요. `<= 0`이면 exit `2`.
</ParamField>

<ParamField body="--target-tty" type="string">
외부 측정 tty (`/dev/ttys147` 또는 bare name). 생략 시 tty 검사는 `skipped:…`이고 full `CLOSED` 불가.
</ParamField>

<ParamField body="--execute" type="boolean">
없으면 `DRY_RUN`. 있으면 `orca terminal close --terminal <handle> --json` 후 소멸 측정.
</ParamField>

### 후보 해석

1. `--target-handle` / `--target-pty-id` / `--target-session-id` 중 하나라도 있으면 **exact** 매칭만 사용.
2. 없으면 `--expected`(또는 selector 문자열)로 여러 필드 **부분 문자열** 매칭.
3. 후보 0개 → `REFUSED`
4. 후보 2개 이상 → `REFUSED` (`ambiguous predecessor candidates`)
5. 후보에 `self_handle` 포함 → raise (self close 거부)

### 상태와 disappearances

| `status` | 의미 |
| --- | --- |
| `DRY_RUN` | 후보 1개, `--execute` 없음 |
| `REFUSED` | 후보 없음/모호, close 실패, 또는 소멸 측정 실패(`still_present` 등) |
| `CLOSED` | pane·process·tty 모두 `measured` |
| `CLOSED_PARTIAL` | pane `measured`, still_present 없음, process/tty 중 일부가 `skipped:*` |

`disappearances` 키: `pane`, `process`, `tty`.

- `measured` / `still_present`
- process/tty만 `skipped:no target-pid and no pid reported by terminal list`, `skipped:no target-tty supplied` 등

close 명령 반환값만으로 `CLOSED`를 내지 않는다. 재 list + pid/tty probe가 판정한다.

### JSON 출력 (dry-run 예)

```json
{
  "candidates": [{"handle": "term-u8", "...": "..."}],
  "closed": false,
  "disappearances": {},
  "match_attempts": ["term-u8: handle=term-u8 -> handle"],
  "reason": "dry-run only",
  "status": "DRY_RUN",
  "target_handle": "term-u8"
}
```

## spawn

```bash
scripts/master-succeed spawn \
  --workspace-selector "id:folder:<uuid>" \
  --expected-placement "id:folder:<uuid>" \
  --kickoff-text "Founding master boot" \
  --root /abs/workspace/root \
  --agent claude \
  --model claude-fable-5 \
  --title "Founding master boot" \
  --json \
  --dry-run
```

### 옵션

<ParamField body="--workspace-selector" type="string" required>
`orca terminal create --worktree`에 전달하는 selector. 검증된 형태: `id:<repoId>::<path>`, `id:folder:<uuid>` / `folder:<uuid>`. `path:`는 repository worktree 경로 일치에만 사용.
</ParamField>

<ParamField body="--kickoff-text" type="string">
에이전트 기동 prompt 문자열. `--kickoff-file`과 상호 배타·필수 그룹.
</ParamField>

<ParamField body="--kickoff-file" type="path">
kickoff 본문을 파일에서 읽음.
</ParamField>

<ParamField body="--root" type="path" required>
startup command의 `cd` 대상 및 agent cwd.
</ParamField>

<ParamField body="--title" type="string" required>
Orca pane title. handle reissue 시 title 매칭에 사용.
</ParamField>

<ParamField body="--model" type="string">
에이전트 모델 id. 생략 시 `DEFAULT_MODELS[agent]`, 없으면 exit `2`.
</ParamField>

<ParamField body="--agent" type="string" default="claude">
기동 CLI 이름. `claude`/`claude-code`, `grok`/`grok-build`, `codex`, `cursor`/`cursor-agent`, `agy`, 또는 custom executable.
</ParamField>

<ParamField body="--expected-placement" type="string">
**독립적으로** 기대하는 worktree id. create 응답 `worktreeId`(또는 reissued 세션)와 불일치 시 fail-closed, exit **`26`** (`SPAWN_PLACEMENT_MISMATCH`), 가능하면 생성 터미널 close.
</ParamField>

<ParamField body="--dry-run" type="boolean">
터미널을 만들지 않고 create command / startup_command / verification 계획만 반환.
</ParamField>

### 에이전트 startup command 형태

| agent | 대략적 형태 |
| --- | --- |
| claude / claude-code | `cd ROOT && exec claude --model MODEL --dangerously-skip-permissions KICKOFF` |
| grok / grok-build | `cd ROOT && exec grok --model MODEL --always-approve --cwd ROOT KICKOFF` |
| codex | `cd ROOT && exec codex --model MODEL KICKOFF` (승인 플래그 없음; pretrust 경로 별도) |
| cursor / cursor-agent | `cd ROOT && exec cursor-agent --model MODEL --force --trust KICKOFF` |
| agy | `cd ROOT && exec agy --model MODEL --dangerously-skip-permissions KICKOFF` |
| unknown | `cd ROOT && exec AGENT --model MODEL KICKOFF` (승인 플래그 없음 → prompt-block 가능) |

### fail-closed 검증 순서 (non-dry-run)

```text
scoped terminal list snapshot
  → (best-effort global list snapshot)
  → orca terminal create --worktree SELECTOR --title TITLE --command STARTUP --json
  → parse handle + worktreeId
  → worktree match(selector) else close + SPAWN_WORKTREE_MISMATCH(22)
  → expected_placement match else close + SPAWN_PLACEMENT_MISMATCH(26)
  → scoped re-list liveness
  → reported handle is new+connected+in-worktree → MATCH
  → else unique new titled candidate → MATCH_REISSUED (handle_reissued=true)
  → else SPAWN_HANDLE_STALE(24) without closing unmanaged candidates
```

selector 비교는 `id:` prefix 정규화와 `path:` realpath 매칭을 허용한다. create 응답이 bare `repoId::path`이고 요청이 `id:repoId::path`여도 동일 worktree로 본다.

### JSON 출력

**DRY_RUN:**

```json
{
  "command": ["orca", "terminal", "create", "--worktree", "id:folder:abc", "--title", "master", "--command", "cd /tmp && exec claude --model claude-fable-5 --dangerously-skip-permissions boot", "--json"],
  "handle": null,
  "handle_reissued": false,
  "requested_worktree": "id:folder:abc",
  "startup_command": "cd /tmp && exec claude --model claude-fable-5 --dangerously-skip-permissions boot",
  "status": "DRY_RUN",
  "verification": {
    "agent": "claude",
    "expected_response_field": "worktreeId",
    "fail_closed_action": "terminal close on mismatch",
    "liveness_check": "reported handle must be live+new+connected in requested worktree, else adopt unique titled candidate or fail closed without closing",
    "requested_worktree": "id:folder:abc"
  },
  "verified": false,
  "worktree_id": null
}
```

`--expected-placement`가 있으면 `verification.expected_placement`가 포함된다.

**CREATED (성공):**

| 필드 | 의미 |
| --- | --- |
| `status` | `CREATED` |
| `handle` | 신뢰된 terminal handle (reissue 시 대체 handle) |
| `worktree_id` | 실제 worktree id |
| `requested_worktree` | 요청 selector |
| `verified` | `true` |
| `handle_reissued` | title-unique 재발급 채택 여부 |
| `command` | create argv 배열 |
| `startup_command` | pane 안 shell 문자열 |
| `verification.result` | `MATCH` 또는 `MATCH_REISSUED` |

## Exit 코드

| 코드 | 상수 / 상황 |
| --- | --- |
| `0` | 성공, JSON stdout |
| `2` | 기본 `SuccessionError` (인자 누락, invalid report, self-handle retire 거부, unknown agent without `--model` 등) |
| `20` | `SPAWN_CREATE_ERROR` — `orca terminal create` 실패 또는 create 응답 `ok:false` |
| `21` | `SPAWN_PARSE_ERROR` — create JSON 파싱/필수 필드 누락 |
| `22` | `SPAWN_WORKTREE_MISMATCH` — 응답 worktree ≠ `--workspace-selector` (close 시도) |
| `23` | `SPAWN_CLOSE_ERROR` — mismatch/error 후 생성 터미널 close 실패 |
| `24` | `SPAWN_HANDLE_STALE` — 보고 handle 신뢰 불가, reissue 후보 0/다수 |
| `25` | `SPAWN_LIST_ERROR` — precheck 또는 liveness `terminal list` 실패 |
| `26` | **`SPAWN_PLACEMENT_MISMATCH`** — 실제 worktree ≠ `--expected-placement` (close 시도) |

<Warning>
`--expected-placement`는 “요청이 맞는지”가 아니라 **라인리지/운영 카드가 독립적으로 기대한 좌석**과의 교차 검증이다. selector를 맞춰 녹색만 내는 것은 placement 통과가 아니다.
</Warning>

오류 메시지 예 (stderr):

```text
spawn placement mismatch; closed terminal term-x: expected id:folder:abc, got id:repo::/path
```

선택자 힌트가 붙을 수 있다:

```text
Accepted selector forms are full id:<repoId>::<path>, id:folder:<uuid> for folder workspaces; path: is matched by resolved directory.
```

## 상수 요약

| 영역 | 값 |
| --- | --- |
| Trigger | `IMMEDIATE`, `ADVISORY`, `NONE` |
| Verify | `PASS`, `PARTIAL`, `FAILED` |
| Retire status | `DRY_RUN`, `REFUSED`, `CLOSED`, `CLOSED_PARTIAL` |
| Spawn status | `DRY_RUN`, `CREATED` |
| Disappearance | `measured`, `still_present`, `skipped:…` |

## 운영 흐름 (CLI 조합)

clean succession에서 이 스크립트가 담당하는 측정 표면:

```text
detect → handoff → spawn [--expected-placement] → (boot tools) → verify-successor → retire --execute
```

- founding / successor create: `spawn` (먼저 `--dry-run`)
- empty seat / 이중 마스터: `check-duplicates`
- recovery proof: `verify-successor` (입력 report는 `scripts/master-recover` 등이 산출)
- predecessor teardown: `retire` (handshake 후; `--target-pid`/`--target-tty` 직접 측정)

Lineage append(`src/master_runtime/core/lineage.py`)는 이 CLI의 하위 명령이 아니다. 검증 후 운영 카드/절차가 별도 append한다.

## 관련 bootstrap / recovery 진입점

| 스크립트 | 역할 경계 |
| --- | --- |
| `scripts/master-bootstrap` | charter·handoff·budget 기반 boot block |
| `scripts/master-bootstrap-live` | handoff-dir·role-state 기반 live boot block |
| `scripts/master-recover` | recovery report 산출 (`verify-successor` 입력) |
| `scripts/master-succeed` | 승계 detect·handoff·spawn·duplicate·retire·verify |

## 트러블슈팅 신호

| 증상 | 확인 |
| --- | --- |
| exit `26` | `--expected-placement` vs 실제 `worktreeId`. folder seat에 repo worktree를 넣었는지 재측정 |
| exit `22` | `--workspace-selector` 형태(`path:` 단독 사용 지양, `id:` 선호) |
| exit `24` | create 직후 handle 재발급; title 유일성, unmanaged pane 정리 |
| exit `25` | bare `terminal list` 실패 호스트 → spawn은 scoped list 사용; precheck 실패 원인 확인 |
| retire `CLOSED_PARTIAL` | pid/tty 미전달. folder pane의 null process_id 보완 |
| retire `REFUSED` + still_present | close 후에도 pane/process/tty 생존 → handshake/RST 정책 |
| duplicates non-empty | 이중 마스터 사고 신호. 두 번째 founding 금지 |
| unknown agent exit `2` | 측정된 기본 모델 없음 → `--model` 명시 |

## Next

<CardGroup>
  <Card title="Clean succession" href="/succession">
    handoff → placement spawn → verify → retire → lineage 절차 가이드
  </Card>
  <Card title="마스터 라이프사이클" href="/master-lifecycle">
    founding부터 lineage까지의 generation 루프
  </Card>
  <Card title="Orca 객체 모델" href="/orca-object-model">
    selector 형태, folder seat, worktreeId 판정
  </Card>
  <Card title="방어 인벤토리" href="/defense-inventory">
    placement·duplicate·empty-seat 가드 표
  </Card>
  <Card title="CLI 레퍼런스" href="/cli-reference">
    scripts/ 공개 명령 표와 --help 동기화 계약
  </Card>
  <Card title="Troubleshooting" href="/troubleshooting">
    placement mismatch, seat 중복, revival 복구
  </Card>
</CardGroup>
