<!-- task=08_cli_target_terminology plan=0 tag=CTT -->

# Code Review Reference - CTT

> **[IMPLEMENTING AGENT — READ FIRST] Filling in this file is the mandatory final step of implementation.**

## 개요

date=2026-05-17
task=08_cli_target_terminology, plan=0, tag=CTT

## 이 파일을 읽는 리뷰 에이전트에게

구현과 검증 출력을 대조하고 PASS 시 plan/review를 log로 아카이브하세요.

## 구현 항목별 완료 여부

| 항목 | 완료 여부 |
|---|---|
| [CTT-1] CLI adapter interna.      54544444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444544444444444545444444444444444444444444444444445444444445444444445444444444444444444444444444454444444445444444444444444445444444444444444444444444444444444445444444444444444444444444544444444444444544444444444444444444444444444444444444444444444454444444444444444444444444444444444444444444444444444444444444444445444444444444444444444444444444444444544444444444444444544444444544444444444454445444444444444444444545444444444444444444444444444454444444444444444444444444444444444444444444445444444444444444444444444444444444444444444544444444444444444444544444444544444444444444444544444444444444444544444544454444445445444444444444444444444444444444444444544454544444444444444444444444445444444444445444444444444444454444444445544444444444545444445544544454444444445444444445444454444444454444444444444544544444444444455444454444454454444444444444544454444444444444444444544454444444544444554444444444444444544444454444445444444444444444444454444444444445444444544444444444444444445444444444444454445444444444444544445444444444444444444444444444445544444444444445444444444444444444444444444444444444444444454444445454444444444444444444444444444455444544445444444444444444444444544444444444444544444544444444444544444444444444444444444444444444444454444444444444444444445444444444444444544544444444445444444444544444444445444444444444444444444444444544444444444454444444444444544444444444445544444444444544444444444544444444444454444444444444544544444444444444544444444444444445444444444444444444444444454444444444444444444ls rename | [x] |
| [CTT-2] status checker terminology compatibility | [x] |

## 계획 대비 변경 사항

- 계획 그대로 실행. 내부 식별자에 `target`을 선택했다. (`profile`은 `config.CLIProfileConf` 값을 가리키는 기존 용례와 겹치므로 변수/필드명 충돌을 피하기 위함.)
- 외부에 노출되는 `runtime.SessionTerminator.TerminateSession(ctx, target, sessionID)` 시그니처와 일치하도록 `CLI.TerminateSession`의 매개변수 이름도 `agent` → `target`으로 정리했다.
- provider별 외부 포맷(`"agent"` JSON payload, `--agent` opencode 플래그, `agent_message` SSE event 등)은 변경하지 않았다.

### 수정 파일

- `apps/node/internal/adapters/cli/cli.go`
  - `sessionKey.agent` → `sessionKey.target`
  - `cliAgentName` → `cliTargetName`
  - `StatusChecker` 시그니처의 `agent` 매개변수명 → `target`
  - error/log text: `unknown agent` → `unknown target`, `start agent` → `start target`, `no session %q for agent %q` → `no session %q for target %q`, `zap.String("agent", ...)` → `zap.String("target", ...)`
  - `TerminateSession(_, agent, ...)` → `TerminateSession(_, target, ...)`
- `apps/node/internal/adapters/cli/codex_exec.go`
  - 로컬 변수 `agent` → `target`, `sessionKey{agent: ...}` → `sessionKey{target: ...}`, error text `no persistent session for agent` → `no persistent session for target`
- `apps/node/internal/adapters/cli/persistent.go`
  - 로컬 변수 `agent` → `target`, `sessionKey{...}` 필드 갱신
  - `agent %q has no command` → `target %q has no command`
  - `drainUntilIdle(..., key.agent)` → `key.target`
  - `profileSession.name = key.agent` → `key.target`
  - cancel drain log: `zap.String("agent", key.agent)` → `zap.String("target", key.target)`
- `apps/node/internal/adapters/cli/opencode_sse.go`
  - `resolveOpencodeSession` 내부 변수/필드/error 동일하게 갱신 (외부 `--agent` 플래그 파서, `opencodeRunOpts.Agent`, JSON `"agent"` payload는 그대로)
- `apps/node/internal/adapters/cli/status/status.go`
  - `CheckUsage(ctx, agent, profile)` → `(ctx, target, profile)`
  - `NewChecker(agent, profile)` → `(target, profile)` (switch 분기도 같이)
  - error `status check not supported for agent %q` → `for target %q`
  - 패키지 doc comment의 `agent CLI` → `CLI target`
- `apps/node/internal/adapters/cli/status/status_test.go`
  - `TestUnsupportedAgentReturnsError` → `TestUnsupportedTargetReturnsError`
- `apps/node/internal/adapters/cli/lifecycle_blackbox_test.go`
  - `StatusChecker` 콜백의 `agent` 매개변수명/local check 갱신
  - `unknown agent` error 기대값 → `unknown target`

## 주요 설계 결정

- `target` vs `profile`: `target`은 adapter 도메인 용어(`runtime.SessionTerminator`, `runtime.ExecutionSpec.Target`)와 정렬되고, `profile`은 `config.CLIProfileConf` 변수명과 충돌하기 때문에 `target`을 채택.
- 외부 포맷 보존: `opencode_sse.go`의 `--agent` 파서, `opencodeRunOpts.Agent`, `payload["agent"] = opts.Agent` 등 OpenCode 서버 contract는 변경 범위 외(`agent_message`도 동일).
- `node` 도메인 룰의 “내부 실행 식별자는 `adapter + target`” 원칙을 따른다. behavior change 없음(필드명/문자열/매개변수명만 변경).

## 리뷰어를 위한 체크포인트

- [x] Provider-specific `agent_message` 같은 외부 포맷을 바꾸지 않았는가. — opencode `--agent`/payload `agent` 등 OpenCode 서버 contract는 그대로.
- [x] Error/log text가 target/profile 용어로 정리됐는가. — `unknown target`, `no session for target`, `start target`, `target %q has no command`, `not supported for target`, `zap.String("target", ...)`로 통일.
- [x] CLI blackbox tests가 통과했는가. — `apps/node/internal/adapters/cli` 및 `status` 패키지 PASS.

## 검증 결과

### 잔여 용어 검사

```
$ rg --sort path -n "unknown agent|for agent|zap.String\(\"agent\"|sessionKey\{agent|cliAgentName" apps/node/internal/adapters/cli
(no matches)
```

### CLI 대상 테스트

```
$ go test -count=1 ./apps/node/internal/adapters/cli ./apps/node/internal/adapters/cli/status
ok  	iop/apps/node/internal/adapters/cli	87.675s
ok  	iop/apps/node/internal/adapters/cli/status	30.943s
```

### 전체 테스트

```
$ go test -count=1 ./...
?   	iop/apps/control-plane/cmd/control-plane	[no test files]
?   	iop/apps/edge/cmd/edge	[no test files]
ok  	iop/apps/edge/internal/bootstrap	0.007s
ok  	iop/apps/edge/internal/events	0.008s
ok  	iop/apps/edge/internal/node	0.008s
ok  	iop/apps/edge/internal/opsconsole	0.006s
ok  	iop/apps/edge/internal/service	0.004s
ok  	iop/apps/edge/internal/transport	0.007s
?   	iop/apps/node/cmd/node	[no test files]
ok  	iop/apps/node/internal/adapters	0.005s
ok  	iop/apps/node/internal/adapters/cli	87.681s
?   	iop/apps/node/internal/adapters/cli/internal/testutil	[no test files]
ok  	iop/apps/node/internal/adapters/cli/status	30.975s
?   	iop/apps/node/internal/adapters/mock	[no test files]
?   	iop/apps/node/internal/adapters/ollama	[no test files]
?   	iop/apps/node/internal/adapters/vllm	[no test files]
ok  	iop/apps/node/internal/bootstrap	0.162s
ok  	iop/apps/node/internal/node	0.008s
ok  	iop/apps/node/internal/router	0.004s
?   	iop/apps/node/internal/runtime	[no test files]
ok  	iop/apps/node/internal/store	0.028s
ok  	iop/apps/node/internal/transport	0.006s
?   	iop/apps/worker/cmd/worker	[no test files]
?   	iop/packages/auth	[no test files]
ok  	iop/packages/config	0.007s
?   	iop/packages/events	[no test files]
?   	iop/packages/jobs	[no test files]
?   	iop/packages/metadata	[no test files]
?   	iop/packages/observability	[no test files]
?   	iop/packages/policy	[no test files]
?   	iop/packages/version	[no test files]
```

## 코드리뷰 결과

- 종합 판정: PASS
- 차원별 평가: correctness=Pass, completeness=Pass, test coverage=Pass, API contract=Pass, code quality=Pass, plan deviation=Pass, verification trust=Pass
- 발견된 문제:
  - Nit: `apps/node/internal/adapters/cli/lifecycle_blackbox_test.go:388`의 테스트 함수명 `TestCLIHandleCommandUsageStatusUsesSelectedAgent`에 `Agent` 용어가 남아 있다. 동작 영향은 없고 외부 contract도 아니므로 PASS를 막지는 않는다. 다음 용어 정리 시 `...UsesSelectedTarget`로 맞추면 더 깔끔하다.
- 리뷰 중 재검증:
  - `rg --sort path -n "unknown agent|for agent|zap.String\\(\"agent\"|sessionKey\\{agent|cliAgentName" apps/node/internal/adapters/cli` → no matches
  - `go test -count=1 ./apps/node/internal/adapters/cli ./apps/node/internal/adapters/cli/status` → PASS (`cli` 87.443s, `status` 30.812s)
  - `go test -count=1 ./...` → PASS
- 다음 단계: PASS - active plan/review를 archive하고 `complete.log`를 작성한다.
- 코드리뷰 전용 종료 체크리스트:
  - [x] `코드리뷰 결과`에 `PASS`, `WARN`, `FAIL` 중 하나의 판정을 append한다.
  - [x] 판정과 `차원별 평가`, Required/Suggested/Nit 분류가 서로 일치한다.
  - [x] active `CODE_REVIEW-*-G??.md`를 `code_review_{review_lane}_GNN_N.log`로 아카이브한다.
  - [x] active `PLAN-*-G??.md`를 `plan_{build_lane}_GNN_M.log`로 아카이브한다.
  - [x] PASS이면 `complete.log`를 작성하고 active `.md` 파일을 남기지 않는다.
  - [x] WARN/FAIL이면 다음 active `PLAN-{build_lane}-GNN.md`와 `CODE_REVIEW-{review_lane}-GNN.md`를 작성하고 `complete.log`를 작성하지 않는다.
