<!-- task=m-multi-edge-operations/02+01_edge_fleet_ops plan=3 tag=REVIEW_REVIEW_REVIEW_API -->

# Plan - REVIEW_REVIEW_REVIEW_API Session Propagation Coverage

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

`CODE_REVIEW-cloud-G06.md`의 구현 에이전트 소유 섹션을 채우는 것이 구현의 마지막 단계다. 코드 변경, 테스트 실행, 실제 stdout/stderr 기록을 끝낸 뒤 active 파일을 그대로 두고 리뷰 준비를 보고한다. 최종 판정, log rename, `complete.log`, archive 이동은 code-review 전용이다.

구현 중 사용자만 결정할 수 있는 scope 변경, 사용자 소유 외부 환경/secret, 또는 자동 후속으로 해결할 수 없는 차단이 생기면 `CODE_REVIEW-cloud-G06.md`의 `사용자 리뷰 요청` 섹션에 근거와 재개 조건을 채우고 중단한다. 명령 재실행이나 증거 수집으로 닫을 수 있는 공백은 사용자 리뷰 요청이 아니라 구현/검증 항목으로 처리한다.

## 배경

G06 plan=2 follow-up은 connected-node `agent.command` + `parameters.command=capabilities` success path가 실제 `NodeCommandRequest`를 보내는지 검증하도록 요구했다. 현재 테스트는 `NodeCommandRequest.Type`, `Adapter`, `Target`은 확인하지만 explicit `session_id`를 보내지 않고 `NodeCommandRequest.SessionId`도 assert하지 않는다.

이 후속은 기존 success round-trip 테스트의 session propagation만 보강한다. 새 프로토콜, Control Plane API, connector relay, UI 변경은 범위 밖이다.

## 사용자 리뷰 요청 흐름

구현 중 blocker는 active review stub의 `사용자 리뷰 요청` 섹션에 기록한다. code-review가 그 요청을 검증하고 필요할 때만 `USER_REVIEW.md`를 작성한다.

## 분석 결과

### 읽은 파일

- `agent-task/m-multi-edge-operations/02+01_edge_fleet_ops/plan_cloud_G06_2.log`
- `agent-task/m-multi-edge-operations/02+01_edge_fleet_ops/code_review_cloud_G06_2.log`
- `apps/edge/internal/service/service.go`
- `apps/edge/internal/service/service_test.go`
- `agent-test/local/rules.md`
- `agent-test/local/edge-smoke.md`

### 테스트 환경 규칙

- test_env: `local`
- matched profile: `agent-test/local/edge-smoke.md`
- applied commands: service package fresh test, edge package fresh test, `git diff --check`
- no external secret, Docker, Flutter, or remote runner is required for this follow-up.

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

- Missing: `TestServiceExecuteCommandAgentCommandCapabilitiesSuccess` does not send `parameters["session_id"]` and does not assert `NodeCommandRequest.SessionId`.
- Already covered: real `NodeCommandRequest.Type == NODE_COMMAND_TYPE_CAPABILITIES`, adapter/target propagation, completed response/event, downstream node error response and failed event.

### 심볼 참조

- Renamed/removed symbols: none.

### 분할 판단

- Existing split subtask remains `m-multi-edge-operations/02+01_edge_fleet_ops`.
- No additional split: this is one test-coverage repair inside `apps/edge/internal/service`.

### 범위 결정 근거

- Do not change proto schema, Control Plane API, connector relay, or client UI.
- Prefer a test-only change: add an explicit `session_id` parameter to the existing success test and assert `req.GetSessionId()`.
- Production code change is allowed only if the new assertion exposes a real mapping bug in `ExecuteCommand`.

### 빌드 등급

- build=`cloud-G06`, review=`cloud-G06`: this remains a protocol-path coverage repair for a repeated Required issue in the same cloud review lane.

## 구현 체크리스트

- [ ] [REVIEW_REVIEW_REVIEW_API-1] `agent.command` capabilities success test가 explicit `session_id`를 보내고 실제 `NodeCommandRequest.SessionId` 전달을 검증하도록 보강한다.
- [ ] [REVIEW_REVIEW_REVIEW_API-2] fresh service/edge tests와 `git diff --check`를 실행하고 결과를 기록한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

### [REVIEW_REVIEW_REVIEW_API-1] Explicit Session Propagation Test

문제:

`apps/edge/internal/service/service_test.go:604`의 node request listener는 type/adapter/target만 검증한다. `apps/edge/internal/service/service_test.go:636`의 request parameters도 `session_id`를 보내지 않아, `apps/edge/internal/service/service.go:775`의 `session_id` bridge가 깨져도 테스트가 통과한다.

해결 방법:

기존 `TestServiceExecuteCommandAgentCommandCapabilitiesSuccess`를 수정한다. `EdgeCommandRequest.Parameters`에 예를 들어 `"session_id": "session-a"`를 추가하고, fake node listener에서 `req.GetSessionId() == "session-a"`를 assert한다. 현재 구현이 이미 맞다면 service production code는 변경하지 않는다. 새 assertion이 실패하면 `ExecuteCommand`의 `NodeCommandRequestSpec.SessionID` mapping만 고친다.

수정 파일 및 체크리스트:

- [ ] `apps/edge/internal/service/service_test.go`: success request parameters에 explicit `session_id` 추가.
- [ ] `apps/edge/internal/service/service_test.go`: fake node listener에서 `req.GetSessionId()` assertion 추가.
- [ ] `apps/edge/internal/service/service.go`: 필요할 때만 `parameters["session_id"]` propagation 수정.

테스트 작성:

- Update `TestServiceExecuteCommandAgentCommandCapabilitiesSuccess`.

중간 검증:

```bash
go test -count=1 ./apps/edge/internal/service
```

### [REVIEW_REVIEW_REVIEW_API-2] Verification

문제:

이 follow-up은 테스트 신뢰 회복 작업이므로 fresh output이 필요하다.

해결 방법:

대상 package, edge 전체 package, diff cleanliness를 fresh run으로 확인한다.

수정 파일 및 체크리스트:

- [ ] `go test -count=1 ./apps/edge/internal/service`
- [ ] `go test -count=1 ./apps/edge/...`
- [ ] `git diff --check`

테스트 작성:

- 별도 테스트 없음. 위 명령 결과가 검증이다.

중간 검증:

```bash
git diff --check
```

## 수정 파일 요약

| 파일 | 항목 |
|------|------|
| `apps/edge/internal/service/service_test.go` | REVIEW_REVIEW_REVIEW_API-1, REVIEW_REVIEW_REVIEW_API-2 |
| `apps/edge/internal/service/service.go` | REVIEW_REVIEW_REVIEW_API-1 only if the new assertion exposes a production mapping bug |

## 최종 검증

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

예상 결과: 모든 명령 exit code 0. `go test` cache output은 완료 증거로 쓰지 말고 `-count=1` fresh output을 기록한다.

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