<!-- task=11_full_e2e_validation plan=0 tag=FEV -->

# 11 Full E2E Validation Plan - FEV

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

**필수: 구현 마지막에는 반드시 `CODE_REVIEW-*-G??.md`의 모든 섹션을 실제 검증 내용과 명령 출력으로 채운다.**
이 작업은 01-10 후속작업이 모두 완료된 뒤 실행하는 검증 전용 게이트다. 검증을 실행하기 전에 01-10 task의 active `PLAN-*.md`/`CODE_REVIEW-*.md`가 모두 archive되고 `complete.log`가 있는지 확인한다. 구현 에이전트는 review 파일의 `이 파일을 읽는 리뷰 에이전트에게` 섹션에 있는 아카이브 지시를 실행하지 않는다.

## 배경

Edge ops console 유지 방향으로 01-10 후속작업이 만들어졌고, 이 변경들은 `bin/edge.sh` + `bin/node.sh` 사용자 실행 파이프라인, edge service/event/transport, node command, docs/roadmap에 걸쳐 있다. 개별 단위 테스트가 통과해도 실제 bin entrypoint, full-cycle console command, real CLI profile, idle transport regression을 한 번에 확인하지 않으면 사용자가 겪은 `transport_closed` 유형의 문제가 다시 숨어 있을 수 있다. 이 계획은 `e2e-smoke` 스킬 기준으로 전체 E2E 검증과 로드맵/문서 반영 더블체크를 수행한다.

## 분석 결과

### 읽은 파일

- `agent-ops/skills/common/plan/SKILL.md`
- `agent-ops/skills/project/e2e-smoke/SKILL.md`
- `agent-ops/rules/project/domain/testing/rules.md`
- `Makefile`
- `bin/edge.sh`
- `bin/node.sh`
- `README.md`
- `docs/architecture.md`
- `apps/edge/README.md`
- `apps/control-plane/README.md`
- `apps/node/README.md`

### 테스트 커버리지 공백

- 현재 `Makefile`에는 `test-e2e` target이 없다. 10번 작업 완료 전에는 고정 E2E 명령이 없으므로 11번 실행자는 먼저 10번 완료 여부를 확인해야 한다.
- 현재 `scripts` 디렉터리가 없다. 10번 작업이 완료되면 `scripts/e2e-smoke.sh` 또는 동등한 고정 smoke entrypoint가 생겼는지 확인해야 한다.
- `e2e-smoke` 스킬은 mock smoke, full-cycle 실제 구동, real CLI profile 검증을 모두 요구한다. 기존 단위 테스트만으로는 node register, `/nodes`, message x2, session, background, terminate, status, lifecycle event, idle monitor를 커버하지 않는다.
- 이전 논의에서 확인한 문서 리스크가 남아 있다. `README.md`, `docs/architecture.md`, `apps/edge/README.md`는 아직 console을 임시 디버그 UI로 설명하는 라인이 있고, Control Plane 문서에는 ops console을 대체하지 않는다는 경계가 약하다.
- 현재 01-03은 complete 상태이고, 04-10은 active 상태다. 11번 검증은 04-10 완료 전 실행하면 안 된다.

### 심볼 참조

- `make test-e2e`: 현재 `Makefile`에 없음.
- `bin/edge.sh`: `bin/edge.sh:10`에서 실제 `go run ./apps/edge/cmd/edge console --config "$CONFIG_FILE"` 실행.
- `bin/node.sh`: `bin/node.sh:36`에서 실제 `go run ./apps/node/cmd/node serve --config "$CONFIG_FILE"` 실행.
- `임시 디버그`: `docs/architecture.md:51`, `apps/edge/README.md:12`.
- `임시 수동 테스트 UI`: `README.md:217`.

### 범위 결정 근거

- 이 task는 검증 전용이다. 실패를 고치는 코드 변경은 이 task에서 바로 섞지 않는다. 실패가 나오면 실패 로그와 재현 명령을 `CODE_REVIEW-cloud-G09.md`에 기록하고 후속 task를 만든다.
- 기본 E2E smoke는 mock adapter를 사용할 수 있지만, 반드시 실제 `bin/edge.sh`와 `bin/node.sh`를 실행해야 한다. in-process mock pipeline이나 임시 우회 실행은 금지한다.
- real CLI profile 검증은 mock으로 대체하지 않는다. command/login/provider/workspace 문제로 실행하지 못하면 profile별 blocker로 기록한다.
- 기본 `configs/*.yaml`은 오염시키지 않는다. 임시 config 파일 또는 환경 변수 override만 사용한다.
- 문서 더블체크는 직접 문서 수정이 아니라 검증 항목이다. 문서 내용이 맞지 않으면 09번 작업 미완료 또는 후속 문서 task 필요로 FAIL/WARN 처리한다.

### 빌드 등급

- Build `cloud-G09`: bin script orchestration, stdout/stderr contract, real external CLI profile, long-running idle monitor, multi-task completion gate를 포함한다.
- Review `cloud-G09`: 검증 출력의 신뢰성, 실제 bin 사용 여부, real CLI blocker 처리, 로드맵 문서 정합성을 모두 재확인해야 한다.

## 의존 관계 및 구현 순서

이 작업은 반드시 01-10 이후에 실행한다. 특히 active plan이 남아 있는 `04_edge_operation_contract`, `05_event_bus_replay`, `06+run_event_node_label`, `07_node_command_ops_surface`, `08+cli_target_terminology`, `09_ops_console_docs`, `10_bin_e2e_smoke`가 모두 complete 상태가 되기 전에는 검증을 시작하지 않는다.

### [FEV-1] 01-10 작업 완료 게이트 확인

#### 문제

현재 01-03은 complete 상태지만 04-10은 active plan이 남아 있다. 11번 E2E를 먼저 실행하면 아직 바뀌는 중인 service/event/proto/docs/bin 경로를 검증하게 된다.

#### 해결 방법

다음 폴더가 모두 `complete.log`를 가지고, active `PLAN-*.md`/`CODE_REVIEW-*.md`가 없는지 확인한다.

```text
agent-task/01+edge_runtime_common
agent-task/02+edge_opsconsole_package
agent-task/03+service_source_metadata
agent-task/04_edge_operation_contract
agent-task/05_event_bus_replay
agent-task/06+run_event_node_label
agent-task/07_node_command_ops_surface
agent-task/08+cli_target_terminology
agent-task/09_ops_console_docs
agent-task/10_bin_e2e_smoke
```

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

- [ ] `CODE_REVIEW-cloud-G09.md`에 task 상태 확인 출력 기록
- [ ] active plan이 남아 있으면 즉시 중단하고 미완료 task 목록 기록
- [ ] `complete.log`가 없는 task를 blocker로 기록

#### 테스트 작성

- 별도 테스트 작성 없음. 검증 명령 출력이 evidence다.

#### 중간 검증

```bash
for d in agent-task/01+edge_runtime_common agent-task/02+edge_opsconsole_package agent-task/03+service_source_metadata agent-task/04_edge_operation_contract agent-task/05_event_bus_replay agent-task/06+run_event_node_label agent-task/07_node_command_ops_surface agent-task/08+cli_target_terminology agent-task/09_ops_console_docs agent-task/10_bin_e2e_smoke; do test -f "$d/complete.log" || { echo "missing complete.log: $d"; exit 1; }; done
for d in agent-task/01+edge_runtime_common agent-task/02+edge_opsconsole_package agent-task/03+service_source_metadata agent-task/04_edge_operation_contract agent-task/05_event_bus_replay agent-task/06+run_event_node_label agent-task/07_node_command_ops_surface agent-task/08+cli_target_terminology agent-task/09_ops_console_docs agent-task/10_bin_e2e_smoke; do find "$d" -maxdepth 1 \( -name 'PLAN-*.md' -o -name 'CODE_REVIEW-*.md' \) -print; done
```

Expected: first command exits 0. Second command prints nothing.

### [FEV-2] 전체 Go 테스트와 proto/generated 정합성 확인

#### 문제

01-10은 bootstrap, opsconsole, service, events, proto, node command, CLI adapter, docs, E2E script를 건드릴 수 있다. 개별 task 검증만으로 전체 package 조합이 깨졌는지 알 수 없다.

#### 해결 방법

- Fresh `go test -count=1 ./...`를 실행한다.
- proto 변경이 있었다면 `make proto` 또는 generated diff 정합성을 확인한다.
- 검증 출력은 요약이 아니라 실제 stdout/stderr를 기록한다. 너무 길면 `/tmp/iop-fev-*.log`에 저장하고 exact command와 path를 기록한다.

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

- [ ] `CODE_REVIEW-cloud-G09.md`에 Go test output 기록
- [ ] proto 변경 여부 확인 기록
- [ ] 실패 시 고치지 말고 재현 명령과 실패 package 기록

#### 테스트 작성

- 별도 테스트 작성 없음. 전체 test run이 검증이다.

#### 중간 검증

```bash
go test -count=1 ./...
git diff --name-only -- proto/iop proto/gen/iop
```

Expected: Go tests pass. Proto source/generated diff가 있으면 해당 task review에 `make proto` 실행 증거가 있어야 한다.

### [FEV-3] 공식 E2E smoke entrypoint 검증

#### 문제

`e2e-smoke` 스킬은 `make test-e2e` 같은 고정 명령이 있으면 우선 사용하라고 한다. 현재 10번 완료 전에는 target이 없으므로, 11번 실행 시점에는 10번이 만든 target/script가 실제로 존재하고 bin entrypoint를 사용하는지 확인해야 한다.

#### 해결 방법

- `make test-e2e` target 존재를 확인한다.
- smoke script가 있다면 실제 `bin/edge.sh`와 `bin/node.sh`를 호출하는지 검색한다.
- `make test-e2e`를 실행한다.
- 기본 smoke는 mock adapter여도 된다. 단, edge/node는 실제 bin script로 띄워야 한다.

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

- [ ] `CODE_REVIEW-cloud-G09.md`에 `make test-e2e` 출력 기록
- [ ] smoke script의 bin usage search 출력 기록
- [ ] 기본 config 오염 여부 기록

#### 테스트 작성

- 별도 테스트 작성 없음. `make test-e2e`가 검증이다.

#### 중간 검증

```bash
make -n test-e2e
rg --sort path -n "bin/edge\\.sh|bin/node\\.sh|IOP_EDGE_CONFIG|IOP_NODE_CONFIG|mktemp|configs/edge\\.yaml|configs/node\\.yaml" Makefile scripts README.md apps/edge/README.md
make test-e2e
git diff -- configs/edge.yaml configs/node.yaml
```

Expected: dry-run shows `test-e2e`; search proves actual bin scripts and temp config/override usage; `make test-e2e` passes; config diff is empty.

### [FEV-4] Full-cycle 실제 구동 검증

#### 문제

Mock smoke만으로는 foreground/background/session/status/terminate/lifecycle 흐름과 console 출력 라우팅이 실제 사용자 방식으로 유지되는지 충분히 검증하지 못한다.

#### 해결 방법

`e2e-smoke` 스킬의 full-cycle 항목을 실제 `bin/edge.sh` + `bin/node.sh`로 수행한다. 명령을 한꺼번에 stdin에 밀어 넣지 말고 기대 출력이 나타난 뒤 다음 명령을 보낸다.

검증 cycle:
- startup/register: edge start, node wait/register, `/nodes`
- foreground: same session message x2
- session: `/session <id>` 후 message
- background: `/background on`, async start/message/complete, `/background off`
- terminate: `/terminate-session`
- status: `/status`
- lifecycle: node disconnect event
- routing: 가능하면 2 nodes로 ambiguous error와 `/node <id|alias>` selection

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

- [ ] `CODE_REVIEW-cloud-G09.md`에 full-cycle 실행 방식 기록
- [ ] 사용한 temp config path와 port 기록
- [ ] 각 cycle pass/fail 기록
- [ ] 실패 시 로그 path와 재현 명령 기록

#### 테스트 작성

- 별도 테스트 작성 없음. Full-cycle run output이 검증이다.

#### 중간 검증

```bash
make test-e2e
```

Expected: `make test-e2e`가 full-cycle을 포함하도록 10번에서 구현되어 있어야 한다. 포함하지 않는다면 이 항목은 FAIL이고, 10번 follow-up이 필요하다.

### [FEV-5] Real CLI profile 검증과 idle transport regression

#### 문제

사용자는 mock이 아니라 실제 Gemini 같은 외부 CLI를 통해 idle 상태에서 `transport_closed`가 발생하는지 확인하라고 요구한 이력이 있다. 전체 E2E에서도 실제 CLI profile을 mock으로 대체하면 같은 문제가 재발할 수 있다.

#### 해결 방법

- 실제 CLI command availability를 확인한다.
- 최소 Gemini profile은 실제 메시지 1회 이상 전송한다.
- 가능하면 `claude`, `gemini`, `codex`, `opencode` 각각 same session message x2와 `/status`를 수행한다.
- Gemini 또는 사용 가능한 real profile 하나는 message complete 후 10분 idle monitor를 수행한다.
- monitor 중 `transport_closed`, `transport_close_reason`, `heartbeat_timeout`, `node unregistered`, `disconnected from edge`가 없어야 한다.

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

- [ ] `CODE_REVIEW-cloud-G09.md`에 profile별 command availability 기록
- [ ] profile별 pass/fail/blocker 기록
- [ ] Gemini 또는 실제 profile idle 10분 monitor 출력 기록
- [ ] mock으로 대체한 profile이 있으면 blocker로 기록, pass로 처리하지 않음

#### 테스트 작성

- 별도 테스트 작성 없음. 실제 external CLI output이 검증이다.

#### 중간 검증

```bash
for c in claude gemini codex opencode; do command -v "$c" || true; done
IOP_E2E_PROFILE=gemini make test-e2e
```

Expected: Gemini command가 있으면 실제 Gemini run이 pass하고, 10분 idle monitor에서 transport close 관련 라인이 없어야 한다. Gemini command/login/provider 문제면 blocker로 기록하고 다른 available real profile로 같은 monitor를 수행한다.

### [FEV-6] 로드맵/문서 방향성 더블체크

#### 문제

작업 중 모델들이 `README.md`와 `apps/control-plane/README.md`를 이미 수정 중이었다. 문서를 사전에 직접 반영하면 충돌 가능성이 있었고, 기존 문서에는 `임시 디버그 클라이언트`, `임시 수동 테스트 UI` 표현이 남아 있었다.

#### 해결 방법

다음 내용을 문서에서 확인한다.
- Edge console은 temporary UI가 아니라 `edge-local ops console` 또는 동등한 유지 대상 진단 표면으로 설명된다.
- Control Plane/Portal은 ops console을 대체하지 않고, Edge service/command/event contract를 중앙에서 소비하는 표면으로 설명된다.
- Roadmap Phase 1/2 또는 별도 항목에 ops console hardening, service/event contract, NodeCommand ops surface, event replay/drop stats, bin E2E smoke가 반영된다.
- Node README에서 `console.target` 표현은 유지하더라도 edge-local ops console과 node `cli adapter`가 구분된다.

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

- [ ] `README.md` search 결과 기록
- [ ] `docs/architecture.md` search 결과 기록
- [ ] `apps/edge/README.md` search 결과 기록
- [ ] `apps/control-plane/README.md` search 결과 기록
- [ ] `apps/node/README.md` search 결과 기록
- [ ] mismatch가 있으면 09번 미완료 또는 후속 docs task 필요로 기록

#### 테스트 작성

- 별도 테스트 작성 없음. Deterministic search output이 검증이다.

#### 중간 검증

```bash
rg --sort path -n "임시 디버그|temporary debug|임시 수동 테스트 UI|수동 테스트 도구로만" README.md docs apps/edge apps/control-plane apps/node
rg --sort path -n "edge-local ops console|ops console|diagnostic surface|Control Plane.*대체|service.*event|NodeCommand|test-e2e|E2E smoke" README.md docs apps/edge apps/control-plane apps/node
```

Expected: first command prints nothing, or only explicitly justified historical notes. Second command shows the new direction in root README, architecture, edge README, and control-plane README.

### [FEV-7] 작업 중 충돌/사전 반영 리스크 더블체크

#### 문제

이전 확인 시 `README.md`, `apps/control-plane/README.md`, edge runtime/transport files가 dirty였다. 11번 실행 시점에도 다른 작업이 active이면 검증 결과가 불안정해진다.

#### 해결 방법

- 01-10 active plan이 없는지 확인한다.
- `git status --short`를 기록한다.
- docs files가 아직 변경 중이면 누가 어떤 task에서 만졌는지 task review logs와 대조한다.
- 검증 중 새 코드 수정은 하지 않는다.

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

- [ ] `git status --short` 출력 기록
- [ ] active task 없음 확인
- [ ] docs mismatch와 dirty state를 구분해 기록

#### 테스트 작성

- 별도 테스트 작성 없음.

#### 중간 검증

```bash
git status --short
find agent-task/01+edge_runtime_common agent-task/02+edge_opsconsole_package agent-task/03+service_source_metadata agent-task/04_edge_operation_contract agent-task/05_event_bus_replay agent-task/06+run_event_node_label agent-task/07_node_command_ops_surface agent-task/08+cli_target_terminology agent-task/09_ops_console_docs agent-task/10_bin_e2e_smoke -maxdepth 1 \( -name 'PLAN-*.md' -o -name 'CODE_REVIEW-*.md' \) -print
```

Expected: active plan/review files from 01-10 are absent. `git status` may show final uncommitted source/doc changes, but no concurrent active task should remain.

## 수정 파일 요약

| 파일 | 항목 |
|---|---|
| `agent-task/11_full_e2e_validation/CODE_REVIEW-cloud-G09.md` | FEV-1, FEV-2, FEV-3, FEV-4, FEV-5, FEV-6, FEV-7 |
| `/tmp/iop-fev-*.log` | FEV-2, FEV-3, FEV-4, FEV-5 |

## 최종 검증

Go test cache output is not acceptable; use fresh execution.

```bash
for d in agent-task/01+edge_runtime_common agent-task/02+edge_opsconsole_package agent-task/03+service_source_metadata agent-task/04_edge_operation_contract agent-task/05_event_bus_replay agent-task/06+run_event_node_label agent-task/07_node_command_ops_surface agent-task/08+cli_target_terminology agent-task/09_ops_console_docs agent-task/10_bin_e2e_smoke; do test -f "$d/complete.log" || { echo "missing complete.log: $d"; exit 1; }; done
for d in agent-task/01+edge_runtime_common agent-task/02+edge_opsconsole_package agent-task/03+service_source_metadata agent-task/04_edge_operation_contract agent-task/05_event_bus_replay agent-task/06+run_event_node_label agent-task/07_node_command_ops_surface agent-task/08+cli_target_terminology agent-task/09_ops_console_docs agent-task/10_bin_e2e_smoke; do find "$d" -maxdepth 1 \( -name 'PLAN-*.md' -o -name 'CODE_REVIEW-*.md' \) -print; done
go test -count=1 ./...
make -n test-e2e
make test-e2e
for c in claude gemini codex opencode; do command -v "$c" || true; done
IOP_E2E_PROFILE=gemini make test-e2e
rg --sort path -n "임시 디버그|temporary debug|임시 수동 테스트 UI|수동 테스트 도구로만" README.md docs apps/edge apps/control-plane apps/node
rg --sort path -n "edge-local ops console|ops console|diagnostic surface|Control Plane.*대체|service.*event|NodeCommand|test-e2e|E2E smoke" README.md docs apps/edge apps/control-plane apps/node
git diff -- configs/edge.yaml configs/node.yaml
git status --short
```

Pass condition:
- 01-10 complete gate passes.
- No active 01-10 plan/review files remain.
- `go test -count=1 ./...` passes.
- `make test-e2e` passes using actual `bin/edge.sh` and `bin/node.sh`.
- Full-cycle cycles are included and pass, or missing cycle is marked FAIL with follow-up.
- Gemini real profile passes or is explicitly blocker; at least one available real profile performs a 10-minute idle monitor without transport close lines.
- Roadmap/docs no longer describe ops console as temporary-only and clearly state Control Plane does not replace edge-local diagnostics.
- `configs/edge.yaml` and `configs/node.yaml` have no E2E temp diff.

모든 코드 변경 완료 후 반드시 `CODE_REVIEW-*-G??.md`의 전체 섹션을 채운다. 이 파일 작성이 구현의 마지막 단계다.
