<!-- task=10_bin_e2e_smoke plan=1 tag=REVIEW_BES -->

# 10 Bin E2E Smoke Follow-up Plan - REVIEW_BES

## 이 파일을 읽는 구현 에이전트에게

이 plan은 이전 리뷰의 Required 이슈를 해소한다. 핵심 목표는 `make test-e2e`가 실제 실패를 숨기지 않고, mock smoke와 real CLI profile 검증을 정직하게 구분하도록 만드는 것이다.

구현 마지막에는 반드시 `CODE_REVIEW-cloud-G07.md`의 모든 구현 소유 섹션을 실제 구현 내용과 명령 출력으로 채운다. 검증 출력에는 `...`를 쓰지 않는다.

## 배경

이전 구현은 `make test-e2e` target과 `scripts/e2e-smoke.sh`를 추가했지만, 재실행 결과 mock/real profile 모두 `/status` 또는 `/terminate-session` 실패를 포함해도 `Smoke test PASSED`로 종료했다. `IOP_E2E_PROFILE=gemini` 경로도 실제 Gemini profile 대신 임시 `echo` profile을 만들고 있어 real CLI 검증이 아니다.

## 구현 체크리스트

- [ ] [REVIEW_BES-1] `IOP_E2E_PROFILE` real profile 검증이 실제 CLI profile을 사용하거나 명확히 BLOCKED/FAILED를 보고한다.
- [ ] [REVIEW_BES-2] smoke assertion이 `/status`, `/terminate-session`, node/console error를 숨기지 않는다.
- [ ] [REVIEW_BES-3] 검증 결과와 review reference를 실제 stdout/stderr로 갱신한다.
- [ ] [REVIEW_BES-FINAL] `CODE_REVIEW-cloud-G07.md`의 구현 소유 섹션을 모두 채운다.

## [REVIEW_BES-1] real profile 검증 정직성 복구

### 문제

`scripts/e2e-smoke.sh`는 `PROFILE != mock`이어도 임시 edge config에 `command: "echo"` profile을 생성한다. 이 경로는 실제 `configs/edge.yaml`의 CLI profile이나 외부 CLI를 호출하지 않으므로 real profile 검증이 아니다. 그런데 status error가 있어도 `REAL_PROFILE_STATUS=PASSED`가 될 수 있다.

### 해결 방법

- mock 기본 smoke는 외부 CLI 없이 유지한다.
- `IOP_E2E_PROFILE`이 지정되면 선택한 profile의 실제 command/args/output_format을 사용한다.
- 실제 command를 찾을 수 없거나 로그인/권한/remote provider 문제로 실행할 수 없으면 `REAL_PROFILE_STATUS=BLOCKED (...)`를 출력하고 전체 exit code 정책을 명확히 한다.
- 실제 profile 실행 중 `error:`, `node reported error`, `cancel error`, status checker 실패가 나오면 `PASSED`가 아니라 `FAILED` 또는 `BLOCKED`로 분류한다.

### 수정 파일 및 체크리스트

- [ ] `scripts/e2e-smoke.sh`

### 테스트 결정

real profile 검증은 환경 의존성이 있으므로 command missing/login/provider 상태를 BLOCKED로 기록할 수 있다. 다만 fake `echo` profile로 PASS를 만들면 안 된다.

### 중간 검증

```bash
IOP_E2E_PROFILE=gemini make test-e2e
```

## [REVIEW_BES-2] smoke assertion 신뢰성 복구

### 문제

현재 script는 `/terminate-session`의 edge-side send acknowledgement와 몇 개의 run event만 grep한다. mock adapter는 session termination/status command를 지원하지 않는데도 node output의 `does not support session termination`, `does not support commands`를 실패로 처리하지 않는다.

### 해결 방법

- `EDGE_OUT`과 `NODE_OUT` 전체에서 `error:`, `node reported error`, `cancel error`, `does not support`, `startup failed` 등 실패 marker를 검출한다. 지원되지 않는 command를 의도적으로 허용하는 경우는 해당 command를 보내지 않는다.
- `/status`를 검증하려면 `[node-...-status]` 또는 status payload/raw output 같은 실제 성공 출력을 assert한다.
- `/terminate-session`을 검증하려면 node-side cancel/session termination failure가 없음을 assert하고, 가능하면 지원되는 CLI session path에서 실행한다.
- mock adapter로 검증할 수 없는 full-cycle command는 mock smoke와 별도 CLI/fake profile smoke로 분리한다.

### 수정 파일 및 체크리스트

- [ ] `scripts/e2e-smoke.sh`

### 테스트 결정

`make test-e2e`가 failure marker를 숨기지 않는지 확인한다. 필요한 경우 deterministic fake CLI executable을 임시 디렉토리에 만들어 script 안에서 사용하되, real profile 모드와 혼동하지 않는다.

### 중간 검증

```bash
make test-e2e
```

## [REVIEW_BES-3] 검증 기록 및 review reference 복구

### 문제

이전 `CODE_REVIEW-cloud-G07.md`는 plan의 최종 검증인 `go test -count=1 ./...` 결과가 없고, `make test-e2e` 출력도 `...`로 생략했다. 리뷰 중 `go test -count=1 ./...`는 `apps/node/internal/adapters/cli` 구간에서 1분 이상 멈춰 중단되었다.

### 해결 방법

- 후속 수정 후 `go test -count=1 ./...`를 다시 실행한다.
- `make test-e2e`를 실행한다.
- real profile은 가능하면 `IOP_E2E_PROFILE=gemini make test-e2e`를 실행하고, 실행 불가 시 command/login/provider blocker를 실제 출력과 함께 기록한다.
- `CODE_REVIEW-cloud-G07.md`에는 생략 없는 실제 stdout/stderr를 붙인다.

### 수정 파일 및 체크리스트

- [ ] `agent-task/10_bin_e2e_smoke/CODE_REVIEW-cloud-G07.md`

### 테스트 결정

검증 명령 자체가 review trust 회복 기준이다.

### 중간 검증

```bash
go test -count=1 ./...
make test-e2e
```

## 수정 파일 요약

| 파일 | 항목 |
|---|---|
| `scripts/e2e-smoke.sh` | REVIEW_BES-1, REVIEW_BES-2 |
| `agent-task/10_bin_e2e_smoke/CODE_REVIEW-cloud-G07.md` | REVIEW_BES-3, REVIEW_BES-FINAL |

## 최종 검증

```bash
go test -count=1 ./...
make test-e2e
```

가능한 경우:

```bash
IOP_E2E_PROFILE=gemini make test-e2e
```

모든 결과는 PASS/FAILED/BLOCKED를 실제 stdout/stderr와 함께 기록한다.
