<!-- task=m-control-plane-separation-migration/07+05,06_cicd_smoke_evidence plan=0 tag=CICD_SMOKE -->

# Plan - CICD_SMOKE

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

구현 후 반드시 `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 실제 구현 내용, 변경 사유, 검증 출력으로 채운다. 구현 중 사용자만 결정할 수 있는 범위 변경이나 외부 환경 준비가 필요하면 리뷰 stub의 `사용자 리뷰 요청` 섹션에 근거를 적고 멈춘다. 직접 사용자에게 질문하거나 `USER_REVIEW.md`, `complete.log`, archive 로그를 만들지 않는다.

## 배경

`oto-owns-cicd`는 서버 상태 모델과 runner reporting이 모두 동작한 뒤 통합 증거가 있어야 완료 처리할 수 있다. 이 계획은 05/06 완료 후 Go OTO Server와 Dart runner smoke를 확장해 job, execution, log, artifact 상태가 OTO Server에 남는지 검증한다.

## 사용자 리뷰 요청 흐름

구현 중 차단 사유는 active `CODE_REVIEW-*-G??.md`의 `사용자 리뷰 요청` 섹션에 기록한다. 구현 에이전트는 사용자에게 직접 묻지 않고, code-review가 요청 타당성을 판단한다.

## Roadmap Targets

- Milestone: `agent-roadmap/phase/independent-control-plane/milestones/control-plane-separation-migration.md`
- Task ids:
  - `oto-owns-cicd`: OTO Server는 CI/CD runner registry, job, execution history, log/artifact 상태를 소유하고, iop Edge나 iop Control Plane을 전제로 하지 않는다.
- Completion mode: check-on-pass

## 분석 결과

### 읽은 파일

- `agent-roadmap/current.md`
- `agent-roadmap/phase/independent-control-plane/milestones/control-plane-separation-migration.md`
- `agent-test/local/rules.md`
- `agent-test/local/agent-smoke.md`
- `services/core/internal/httpserver/server.go`
- `services/core/internal/httpserver/server_test.go`
- `services/core/internal/runnerregistry/registry.go`
- `apps/runner/lib/oto/agent/edge_registration_client.dart`
- `apps/runner/lib/oto/agent/agent_runner.dart`
- `apps/runner/test/oto_server_connection_smoke_test.dart`
- `apps/runner/test/oto_agent_registration_test.dart`
- `apps/runner/lib/oto/core/build_result.dart`
- `apps/runner/test/oto_application_test.dart`
- `Makefile`

### 테스트 환경 규칙

`test_env=local`이다. `agent-test/local/rules.md`와 `agent-test/local/agent-smoke.md`를 읽었다. 이 계획은 OTO Server registration/bootstrap smoke의 확장이므로 agent-smoke의 `dart analyze`와 지정 Dart test 명령을 최종 검증에 포함한다. Go server fresh test는 repository manifest를 사용해 `cd services/core && go test -count=1 ./...`로 실행한다.

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

- 현재 `oto_server_connection_smoke_test.dart`는 register/online/disconnect와 bootstrap command만 검증한다. job/execution/log/artifact round trip smoke가 없다.
- 현재 Go handler tests는 runner endpoint와 bootstrap만 검증한다. 05에서 추가한 API가 smoke와 같은 JSON shape를 유지하는지 최종 확인이 필요하다.

### 심볼 참조

symbol rename/remove는 계획하지 않는다. 새 smoke test와 필요 시 작은 fixture helper만 추가한다.

### 분할 판단

split 정책을 평가했다. `07+05,06_cicd_smoke_evidence`는 directory name 기준으로 `05+04_core_cicd_state`와 `06+05_runner_dispatch_contract`에 의존한다. 작성 시점에는 둘 다 active plan 상태라 predecessor는 미충족이다. 구현 시작 전 각각의 active 또는 archived `complete.log`를 확인한다.

### 범위 결정 근거

이 계획은 smoke/evidence 전용이다. 새로운 scheduling policy, durable artifact upload, UI, auth는 추가하지 않는다. 05/06에서 구현한 public 표면을 소비해 milestone Task 완료 증거를 수집하는 데 집중한다.

### 빌드 등급

`cloud-G07`. long-running Go server process와 Dart integration smoke, evidence trust가 핵심이라 cloud lane이 적합하다.

## 의존 관계 및 구현 순서

구현 시작 전 아래 predecessor가 PASS 완료되어야 한다.

- `05+04_core_cicd_state`: `complete.log` 필요.
- `06+05_runner_dispatch_contract`: `complete.log` 필요.

## 구현 체크리스트

- [ ] `apps/runner/test/oto_server_connection_smoke_test.dart`에 OTO Server job/execution/log/artifact 상태 round trip smoke를 추가한다.
- [ ] smoke가 iop Edge나 iop Control Plane endpoint를 사용하지 않는지 검증한다.
- [ ] Go/Dart 필수 검증을 실행하고 실제 출력을 review stub에 기록한다.
- [ ] PASS 시 `Roadmap Targets`의 `oto-owns-cicd` 완료 근거로 쓸 수 있도록 검증 내용을 명확히 남긴다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

## [CICD_SMOKE-1] OTO Server CI/CD ownership smoke

### 문제

[oto_server_connection_smoke_test.dart](/config/workspace/oto/apps/runner/test/oto_server_connection_smoke_test.dart:16)는 runner register/online/disconnect만 확인한다. job/execution/log/artifact 상태가 OTO Server에 남는지 검증하지 않는다.

Before:

```dart
16 test(
17   'OTO Dart runner registers with Go OTO Server, goes online, and disconnects on close',
...
143 'OTO Server issues runner bootstrap command and serves bootstrap script',
```

### 해결 방법

05/06에서 추가된 API와 runner helper를 사용해 smoke test를 추가한다. 테스트는 Go OTO Server를 띄우고, runner가 job을 claim/report한 뒤 server API로 execution status, step log, artifact metadata를 조회한다.

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

- [ ] `apps/runner/test/oto_server_connection_smoke_test.dart`: 통합 smoke 추가.
- [ ] 필요 시 `apps/runner/test/oto_agent_registration_test.dart`: helper coverage 보강.
- [ ] 필요 시 `services/core/internal/httpserver/server_test.go`: smoke와 동일 payload shape 보강.

### 테스트 작성

작성한다. 테스트 이름은 `OTO Server owns job execution logs and artifacts reported by runner`로 둔다.

### 중간 검증

```bash
cd apps/runner && dart test test/oto_server_connection_smoke_test.dart
```

기대 결과: All tests passed.

## 수정 파일 요약

| 파일 | 항목 |
|------|------|
| `apps/runner/test/oto_server_connection_smoke_test.dart` | CICD_SMOKE-1 |
| `apps/runner/test/oto_agent_registration_test.dart` | CICD_SMOKE-1 |
| `services/core/internal/httpserver/server_test.go` | CICD_SMOKE-1 |

## 최종 검증

```bash
cd services/core && go test -count=1 ./...
cd apps/runner && dart analyze
cd apps/runner && dart test test/oto_agent_migration_plan_test.dart test/oto_agent_bootstrap_script_test.dart test/oto_agent_cli_test.dart test/oto_agent_config_test.dart test/oto_agent_registration_test.dart test/oto_server_connection_smoke_test.dart
```

기대 결과: 모든 명령 PASS. Go test cache output은 허용하지 않으므로 `-count=1`을 유지한다.

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