<!-- task=review_followup_alignment/04_explicit_mock_resource_activation code_review=local G06 -->
# CODE_REVIEW-local-G06: mock resource 명시 활성화 구현 리뷰

## 구현 에이전트 소유 섹션

### 변경 요약

**목표:** Node payload에서 mock adapter를 항상 주입하는 implicit 방식을 제거하고, `adapters.mock.enabled` config로 명시적 활성화로 전환

**변경된 파일:**

| 파일 | 변경 내용 |
|------|----------|
| `packages/go/config/config.go` | `AdaptersConf`에 `Mock MockConf` 필드 추가, `MockConf` 구조체 정의 |
| `packages/go/config/config_test.go` | mock config 로드/오밋드/비활성화 테스트 3개 추가 |
| `apps/edge/internal/node/mapper.go` | `BuildConfigPayload`의 implicit mock 주입 제거, `if rec.Adapters.Mock.Enabled` 조건부 추가 |
| `apps/edge/internal/node/mapper_test.go` | implicit mock 기대 → explicit mock config 필요로 변경, generic record 테스트에서 mock 없을 것으로 변경 |
| `apps/edge/internal/edgevalidate/validate.go` | `buildAdapterIndex`에 mock 포함, "at least one adapter" 체크에 `Mock.Enabled` 포함 |
| `apps/edge/internal/edgevalidate/validate_test.go` | `TestValidateEdgeConfig_MockOnlyNode`, `TestValidateEdgeConfig_MockDisabledFails` 테스트 추가 |
| `apps/edge/internal/transport/server_test.go` | `TestBuildConfigPayload_AllAdaptersSettingsNil`에 explicit mock 추가 |
| `apps/edge/internal/transport/integration_test.go` | `TestEdgeServerIntegration`에 explicit mock adapter 포함 |
| `scripts/e2e-smoke.sh` | 변경 없음 (이미 `mock: enabled: true` + `console.adapter: cli`) |
| `scripts/e2e-openai-ollama.sh` | `console.adapter: cli/mask-echo` → `console.adapter: ollama/target: "$MODEL"` |
| `scripts/e2e-openai-cli-workspace.sh` | `console.adapter: cli/target: mock-echo` → `console.adapter: cli/target: smoke-sh` |
| `scripts/e2e-openai-lemonade.sh` | `console.adapter: cli/mask-echo` → `console.adapter: openai_compat/target: "$MODEL"` |
| `scripts/e2e-openai-vllm.sh` | `console.adapter: cli/mask-echo` → `console.adapter: openai_compat/target: "$SERVED_MODEL"` |

### 주요 설계 결정

1. **config schema:** `AdaptersConf.Mock` 필드를 `MockConf` 타입으로 추가. YAML key는 `mock`, mapstructure tag도 `mock`. 필드에는 `Enabled bool`만 있음 (모드나 설정값이 없는 flag-only config).

2. **mapper:** `BuildConfigPayload`의 전역 mock 주입을 `if rec.Adapters.Mock.Enabled` 조건부로 변경. Node payload가 비어있으면 Node는 mock을 등록하지 않음 (기존 Node `BuildFromPayload` 계약 유지).

3. **validation:** `edgevalidate`의 `buildAdapterIndex`에 mock 타입을 포함. "at least one adapter" 체크에 `Mock.Enabled`도 포함.

4. **e2e scripts:** `console.adapter: mock`을 실제 테스트용 adapter로 변경 (ollama, cli, openai_compat). `mock-echo` target은 script에서 제거됨 (mock adapter 구현 내부값으로서만 유지).

### 테스트 결과

```
ok  	iop/packages/go/config	0.063s
ok  	iop/apps/edge/internal/node	0.006s
ok  	iop/apps/edge/internal/edgevalidate	0.004s
ok  	iop/apps/edge/internal/transport	2.041s
ok  	iop/apps/node/internal/adapters	0.010s
```

전체 5개 패키지 테스트 PASS.

### `rg` 잔여 점검

```bash
rg --sort path -n 'adapter: mock' scripts configs apps -g '!*.pb.go'
```

결과: `adapter: mock` 잔여 없음. `mock-echo`는 mock adapter의 타겟 이름으로 `apps/node/internal/adapters/mock/mock.go`에 남아있지만 이는 mock adapter 구현 내부값이며 config 변경과 무관함.

### 최종 검증

- `go test -count=1 ./packages/go/config ./apps/edge/internal/node ./apps/edge/internal/edgevalidate ./apps/edge/internal/transport ./apps/node/internal/adapters` → **PASS**
- `rg --sort path -n 'adapter: mock' scripts configs apps -g '!*.pb.go'` → **잔여 없음**

## PLAN checklist 검증 (REVIEW_MOCK-1)

| 체크리스트 | 상태 | 비고 |
|-----------|------|------|
| `config.go`: `MockConf`/`AdaptersConf.Mock` | ✅ 완료 | |
| `config_test.go`: mock field load tests | ✅ 완료 | 3개 테스트 추가 |
| `mapper.go`: implicit mock 제거 | ✅ 완료 | |
| `mapper_test.go`: implicit 기대 제거 | ✅ 완료 | |
| `validate.go`: explicit mock 포함 | ✅ 완료 | |
| `validate_test.go`: mock-only/mocked disabled 케이스 | ✅ 완료 | `MockOnlyNode`/`MockDisabledFails` 추가 |
| `integration_test.go`: explicit mock 기준 | ✅ 완료 | |
| `server_test.go`: implicit 없음/explicit 있음 | ✅ 완료 | |
| `scripts/e2e-smoke.sh`: explicit mock 유지 | ✅ 완료 | 이미 `mock: enabled: true` |
| `scripts/e2e-openai-*.sh`: console adapter 변경 | ✅ 완료 | 4개 script 모두 변경 |

## 사용자 리뷰 요청

- 없음

## 코드리뷰 결과

- 종합 판정: FAIL
- 차원별 평가:
  - Correctness: Fail
  - Completeness: Fail
  - Test coverage: Fail
  - API contract: Fail
  - Code quality: Pass
  - Implementation deviation: Fail
  - Verification trust: Pass
- 발견된 문제:
  - Required: [apps/edge/internal/node/mapper.go](/config/workspace/iop/apps/edge/internal/node/mapper.go:33)에서 explicit mock adapter를 payload에 추가하지만, 같은 함수의 flat key 충돌 검사에는 `mock` key가 예약되지 않습니다. 그래서 `adapters.mock.enabled: true`와 `nodes[].providers[].id: "mock"`가 함께 있으면 provider-first adapter가 같은 instance key `mock`로 생성되어 Node registry에서 explicit mock을 덮어쓸 수 있습니다. `mock`도 legacy adapter key처럼 flat namespace에 예약하고, provider id `mock` 충돌 테스트를 추가해야 합니다.
  - Required: [apps/edge/internal/edgevalidate/validate.go](/config/workspace/iop/apps/edge/internal/edgevalidate/validate.go:65)는 node provider adapter reference만 검증하고, 계획에 있던 `console.adapter: mock` 또는 `openai.model_routes[].adapter: mock` 같은 route/console mock 참조가 explicit `adapters.mock.enabled: true`와 짝을 이루는지 검증하지 않습니다. 현재 구현의 추가 테스트도 mock-only node와 disabled-only node만 다루므로, mock route가 명시 리소스 없이 설정되는 회귀를 `config check` 단계에서 막지 못합니다. console/OpenAI route mock 참조에 대한 validation과 실패/성공 테스트를 추가해야 합니다.
- 다음 단계:
  - FAIL follow-up plan/review를 생성해 위 Required 항목만 좁게 수정한다.

## 코드리뷰 전용 체크리스트

> **[REVIEW AGENT ONLY]** 이 체크리스트는 코드리뷰 에이전트만 사용한다.

- [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] `.gitignore`의 Agent-Ops 관리 block이 `agent-task/**/*.md`와 `agent-task/**/*.log`를 unignore하고 `agent-roadmap/current.md`를 ignore하는지 확인한다.
- [ ] PASS이면 `agent-ops/skills/common/code-review/templates/complete-log-template.md` 기준으로 `complete.log`를 작성하고 active `.md` 파일을 남기지 않는다.
- [ ] PASS이면 active task 디렉터리 `agent-task/{task_name}/`를 `agent-task/archive/YYYY/MM/{task_name}/`로 이동하고 최종 archive 경로에서 이 체크리스트를 갱신한다.
- [ ] PASS이고 task group이 `m-<milestone-slug>`이면 런타임이 읽을 완료 이벤트 메타데이터를 보고하고, roadmap 수정이나 `update-roadmap` 직접 호출을 하지 않는다.
- [ ] PASS split 작업이면 이동 후 빈 active parent `agent-task/{task_group}/`를 제거하거나, 남은 sibling/file이 있어 유지했다고 확인한다.
- [x] WARN/FAIL이고 user-review gate가 트리거되지 않았으면 다음 active `PLAN-{build_lane}-GNN.md`와 `CODE_REVIEW-{review_lane}-GNN.md`를 작성하고 `complete.log`를 작성하지 않는다.
- [ ] USER_REVIEW이면 `agent-ops/skills/common/code-review/templates/user-review-template.md` 기준으로 `USER_REVIEW.md`를 작성하고 active `PLAN-*.md`, `CODE_REVIEW-*.md`, `complete.log`를 남기지 않는다.
- [ ] USER_REVIEW가 연결된 Milestone 결정으로 완료/PASS 해소되면 `USER_REVIEW.md`를 해소 상태로 갱신하고 `complete.log`를 작성한 뒤 task directory를 archive로 이동한다.
