<!-- task=02+01_process_executor_commands plan=0 tag=REFACTOR -->

# ProcessExecutor Command Rollout Plan

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

**구현 마지막 단계에서 `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 반드시 채워야 한다. 해당 파일의 모든 구현 소유 섹션을 채우기 전까지 작업은 완료가 아니다.** 구현 체크리스트와 의존 관계를 지키고, 검증 출력은 review stub에 실제 stdout/stderr로 기록한다. review 파일의 아카이브 지시와 `코드리뷰 전용 체크리스트`는 코드리뷰 에이전트 전용이다.

## 배경

`ProcessExecutor.start/run` 직접 호출이 command 구현에 남아 있어 fake runtime 검증이 불가능한 명령들이 있다. `01_command_runtime_api`에서 runtime 계약을 확장한 뒤, command 인스턴스 내부 호출을 `runtime.start/run`으로 옮긴다.

## 분석 결과

### 읽은 파일

- `lib/oto/commands/command_runtime.dart`
- `lib/oto/commands/aws/awscli.dart`
- `lib/oto/commands/build/build_dart.dart`
- `lib/oto/commands/build/build_dot_net.dart`
- `lib/oto/commands/build/build_ios_archive.dart`
- `lib/oto/commands/build/build_ios_build.dart`
- `lib/oto/commands/build/build_msbuild.dart`
- `lib/oto/commands/build/macos_signing.dart`
- `lib/oto/commands/build/testflight_ios.dart`
- `lib/oto/commands/build/xcodeproj.dart`
- `lib/oto/commands/docker/docker.dart`
- `lib/oto/commands/git/git_hub.dart`
- `lib/oto/commands/gradle/gradle.dart`
- `lib/oto/commands/proto/protobuf.dart`
- `lib/oto/commands/util/execute_app.dart`
- `test/oto_command_runtime_test.dart`

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

- Shell/Git/ProcessRun만 runtime 대역 테스트가 있다.
- build, GitHub, Docker, Gradle, Protobuf, ExecuteApp 명령의 runtime 위임 검증이 없다.
- `decoder`, `workspace`, `printStderr` 옵션 보존 검증이 없다.

### 심볼 참조

- 제거/이름 변경 없음.
- 이전 대상 직접 호출은 `rg --sort path -n "ProcessExecutor\\.(start|run)" lib/oto/commands -g '!command_runtime.dart' -g '!*.g.dart'` 결과 중 command 구현 파일이다.

### 범위 결정 근거

- 이 plan은 `ProcessExecutor.start/run` 직접 호출만 다룬다.
- `Process.run` 기반 SFTP/SMB는 `03+01_sftp_smb_runtime`에서 처리한다.
- core/cli/scheduler의 프로세스 호출은 command 도메인이 아니므로 제외한다.

### 빌드 등급

- build=`cloud-G07`, review=`cloud-G07`: 프로세스 실행 포트 전파와 옵션 보존을 다루는 터미널 에이전트 작업이다.

## 의존 관계 및 구현 순서

- 이 디렉터리 이름의 `+01`은 `agent-task/01_command_runtime_api/complete.log`가 먼저 있어야 함을 뜻한다.
- `01_command_runtime_api` 완료 후 이 plan을 구현한다.

## 구현 체크리스트

- [ ] `ProcessExecutor.start` 직접 호출 command를 `runtime.start`로 이전하고 기존 옵션을 보존한다.
- [ ] `ProcessExecutor.run` 직접 호출 command를 `runtime.run`으로 이전하고 workspace/default runtime 주입을 보존한다.
- [ ] 대표 command fake runtime 회귀 테스트를 추가한다.
- [ ] 중간 검증과 최종 검증 명령을 실행하고 `ProcessExecutor` 잔여 호출을 확인한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

### [REFACTOR-1] ProcessExecutor.start 직접 호출 이전

#### 문제

여러 command가 `ProcessExecutor.start`를 직접 호출해 `CommandRuntime` 주입이 막힌다.

Before:

```dart
// lib/oto/commands/git/git_hub.dart:81
var process = await ProcessExecutor.start(shell,
    decoder: decorder, logHandler: Application.logWithType);
```

#### 해결 방법

command 인스턴스 내부에서는 `runtime.start`를 사용한다. `workspace`, `decoder`, `printStderr`, `logHandler`는 기존 호출과 같은 값으로 넘긴다.

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

- [ ] `lib/oto/commands/aws/awscli.dart`
- [ ] `lib/oto/commands/build/build_dart.dart`
- [ ] `lib/oto/commands/build/build_dot_net.dart`
- [ ] `lib/oto/commands/build/build_ios_archive.dart`
- [ ] `lib/oto/commands/build/build_ios_build.dart`
- [ ] `lib/oto/commands/build/build_msbuild.dart`
- [ ] `lib/oto/commands/build/macos_signing.dart`
- [ ] `lib/oto/commands/build/testflight_ios.dart`
- [ ] `lib/oto/commands/build/xcodeproj.dart`
- [ ] `lib/oto/commands/docker/docker.dart`
- [ ] `lib/oto/commands/git/git_hub.dart`
- [ ] `lib/oto/commands/gradle/gradle.dart`
- [ ] `lib/oto/commands/proto/protobuf.dart`

#### 테스트 작성

작성한다. `GitHubPullRequestList`는 decoder 옵션과 shell을 캡처하고, `BuildMSBuild`는 decoder/printStderr 옵션을 캡처한다.

#### 중간 검증

```bash
dart test test/oto_command_runtime_test.dart
```

예상: 추가 runtime 테스트 통과.

### [REFACTOR-2] ProcessExecutor.run 직접 호출 이전

#### 문제

`BuildiOS`, `TestflightStatusCheck`, `ExecuteApp` 등은 `ProcessExecutor.run`을 직접 호출한다.

Before:

```dart
// lib/oto/commands/build/build_ios_build.dart:58
var process = await ProcessExecutor.run(shell);
```

#### 해결 방법

`runtime.run`으로 이전한다. static helper인 `BuildiOS.initializeFastlane`은 optional runtime 파라미터를 받고, command 호출부에서 `runtime: runtime`을 전달한다.

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

- [ ] `lib/oto/commands/build/build_ios_build.dart`
- [ ] `lib/oto/commands/build/testflight_ios.dart`
- [ ] `lib/oto/commands/util/execute_app.dart`
- [ ] `test/oto_command_runtime_test.dart`

#### 테스트 작성

작성한다. `ExecuteApp`은 `runtime.run(..., workspace: desktop)`을 검증한다. `BuildiOS.initializeFastlane`은 fake runtime으로 `fastlane init` shell이 기록되는지 검증한다.

#### 중간 검증

```bash
dart test test/oto_command_runtime_test.dart
```

예상: 추가 runtime 테스트 통과.

## 수정 파일 요약

| 파일 | 항목 |
|------|------|
| `lib/oto/commands/aws/awscli.dart` | REFACTOR-1 |
| `lib/oto/commands/build/build_dart.dart` | REFACTOR-1 |
| `lib/oto/commands/build/build_dot_net.dart` | REFACTOR-1 |
| `lib/oto/commands/build/build_ios_archive.dart` | REFACTOR-1 |
| `lib/oto/commands/build/build_ios_build.dart` | REFACTOR-1, REFACTOR-2 |
| `lib/oto/commands/build/build_msbuild.dart` | REFACTOR-1 |
| `lib/oto/commands/build/macos_signing.dart` | REFACTOR-1 |
| `lib/oto/commands/build/testflight_ios.dart` | REFACTOR-1, REFACTOR-2 |
| `lib/oto/commands/build/xcodeproj.dart` | REFACTOR-1 |
| `lib/oto/commands/docker/docker.dart` | REFACTOR-1 |
| `lib/oto/commands/git/git_hub.dart` | REFACTOR-1 |
| `lib/oto/commands/gradle/gradle.dart` | REFACTOR-1 |
| `lib/oto/commands/proto/protobuf.dart` | REFACTOR-1 |
| `lib/oto/commands/util/execute_app.dart` | REFACTOR-2 |
| `test/oto_command_runtime_test.dart` | REFACTOR-1, REFACTOR-2 |

## 최종 검증

```bash
test -f agent-task/01_command_runtime_api/complete.log
dart format lib/oto/commands/aws/awscli.dart lib/oto/commands/build/build_dart.dart lib/oto/commands/build/build_dot_net.dart lib/oto/commands/build/build_ios_archive.dart lib/oto/commands/build/build_ios_build.dart lib/oto/commands/build/build_msbuild.dart lib/oto/commands/build/macos_signing.dart lib/oto/commands/build/testflight_ios.dart lib/oto/commands/build/xcodeproj.dart lib/oto/commands/docker/docker.dart lib/oto/commands/git/git_hub.dart lib/oto/commands/gradle/gradle.dart lib/oto/commands/proto/protobuf.dart lib/oto/commands/util/execute_app.dart test/oto_command_runtime_test.dart
dart analyze
dart test test/oto_command_runtime_test.dart
rg --sort path -n "ProcessExecutor\\.(start|run)" lib/oto/commands -g '!command_runtime.dart' -g '!*.g.dart'
```

예상: dependency check 성공, format 정상, analyze/test 통과, 마지막 `rg`는 출력 없음. Dart test는 캐시가 없으므로 fresh 실행만 인정한다.

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