<!-- task=04_edge_operation_contract plan=1 tag=REVIEW_OPC -->

# 04 Edge Operation Contract Follow-up Plan - REVIEW_OPC

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

이 plan은 `code_review_cloud_G08_0.log`에서 나온 Required 이슈만 해결한다. 범위는 formatting 복구와 검증 신뢰 회복으로 제한한다. DTO 구조, opsconsole 출력 문자열, service API shape는 변경하지 않는다.

구현 완료 후 `CODE_REVIEW-cloud-G08.md`의 모든 섹션을 실제 구현 내용과 명령 출력으로 채운다. 리뷰 파일의 아카이브 지시는 리뷰 에이전트가 수행한다.

## 배경

1차 리뷰에서 대상 Go 테스트와 전체 테스트는 통과했지만 `apps/edge/internal/service/service_test.go`가 `gofmt` clean 상태가 아니었다. 또한 이번 변경은 edge service/opsconsole 사용자 실행 파이프라인에 닿으므로, 프로젝트 testing rule에 따라 `bin/edge.sh` + `bin/node.sh` 기반 mock E2E smoke와 full-cycle 실제 구동 검증 결과가 필요하다.

## 분석 결과

### 읽은 파일

- `agent-task/04_edge_operation_contract/code_review_cloud_G08_0.log`
- `agent-ops/rules/project/domain/testing/rules.md`
- `agent-ops/skills/project/e2e-smoke/SKILL.md`
- `apps/edge/internal/service/service_test.go`
- `bin/edge.sh`
- `bin/node.sh`

### 빌드 등급

- Build `cloud-G08`: follow-up에 terminal/bin smoke 검증이 포함된다.
- Review `cloud-G08`: verification trust와 사용자 실행 파이프라인 결과 재검토가 필요하다.

### [REVIEW_OPC-1] service test formatting 복구

#### 문제

`apps/edge/internal/service/service_test.go`가 `gofmt` clean 상태가 아니다.

#### 해결 방법

`gofmt -w apps/edge/internal/service/service_test.go`만 적용한다. formatting-only 변경이며 service 코드 동작은 변경하지 않는다.

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

- [ ] `apps/edge/internal/service/service_test.go`

#### 테스트 결정

formatting-only 변경이므로 `gofmt -l`, `git diff --check`, 대상 패키지 테스트로 검증한다.

#### 중간 검증

```bash
gofmt -l apps/edge/internal/service/service_test.go
git diff --check -- apps/edge/internal/service/service_test.go
go test -count=1 ./apps/edge/internal/service
```

### [REVIEW_OPC-2] E2E/full-cycle 검증 신뢰 회복

#### 문제

1차 `CODE_REVIEW`에는 Go 테스트만 기록되어 있다. 이번 변경 범위는 `apps/edge/internal/service/**`와 `apps/edge/internal/opsconsole/**` 경로에 닿으므로, testing domain rule에 따라 사용자 실행 파이프라인 검증을 보고해야 한다.

#### 해결 방법

`agent-ops/skills/project/e2e-smoke/SKILL.md`를 따라 임시 config/포트로 `bin/edge.sh`와 `bin/node.sh`를 실제 entrypoint로 실행한다. 기본 `configs/*.yaml`은 수정하지 않는다.

검증해야 하는 최소 항목:

- mock adapter 기반 node register 및 `/nodes`
- foreground message 2회, 각 run의 `[edge] sent`, `start`, message/delta, `complete`
- `/session <id>` 후 message 1회
- `/background on` 후 async start/message/complete, 이후 `/background off`
- `/terminate-session` 성공 또는 mock adapter의 명확한 unsupported/error
- `/status` 성공 또는 mock adapter의 명확한 unsupported/error
- node disconnect lifecycle 출력

실제 외부 CLI profile 검증(`claude`, `gemini`, `codex`, `opencode`)을 수행할 수 있으면 profile별 결과를 기록한다. 환경/계정/명령 부재로 수행할 수 없으면 누락하지 말고 profile별 blocker와 남은 위험을 기록한다.

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

- [ ] `agent-task/04_edge_operation_contract/CODE_REVIEW-cloud-G08.md`

#### 테스트 결정

사용자 실행 파이프라인 검증이 목적이므로 테스트 코드는 추가하지 않는다. 대신 실제 명령 stdout/stderr를 `CODE_REVIEW-cloud-G08.md`에 붙인다.

#### 중간 검증

```bash
test -f Makefile && rg -n "test-e2e" Makefile || true
```

고정 `make test-e2e`가 있으면 우선 실행한다. 없으면 `agent-ops/skills/project/e2e-smoke/SKILL.md`의 수동 절차로 임시 config/포트 기반 smoke/full-cycle을 실행하고, 실제 사용한 명령과 stdout/stderr를 `CODE_REVIEW-cloud-G08.md`에 기록한다.

## 수정 파일 요약

| 파일 | 항목 |
|---|---|
| `apps/edge/internal/service/service_test.go` | REVIEW_OPC-1 |
| `agent-task/04_edge_operation_contract/CODE_REVIEW-cloud-G08.md` | REVIEW_OPC-2 |

## 최종 검증

```bash
gofmt -l apps/edge/internal/service/service.go apps/edge/internal/service/service_test.go apps/edge/internal/opsconsole/console.go apps/edge/internal/opsconsole/events.go apps/edge/internal/opsconsole/status.go apps/edge/internal/opsconsole/console_test.go apps/edge/internal/opsconsole/events_test.go apps/edge/cmd/edge/console.go
git diff --check -- apps/edge/internal/service/service.go apps/edge/internal/service/service_test.go apps/edge/internal/opsconsole apps/edge/cmd/edge/console.go
go test -count=1 ./apps/edge/internal/service ./apps/edge/internal/opsconsole ./apps/edge/cmd/edge
go test -count=1 ./...
```

최종 보고에는 Go 테스트, E2E smoke, full-cycle 실제 구동, 실제 외부 CLI profile 검증 수행 여부와 blocker를 모두 명시한다.
