<!-- task=m-cross-os-runner-bootstrap/04+02,03_binary_contract plan=1 tag=REVIEW_BINARY -->

# PLAN: bootstrap binary 검증 명령 실계약 보강

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

이 계획은 직전 코드리뷰 `code_review_local_G06_0.log`의 Required 이슈만 해결한다. 사용자에게 직접 질문하지 말고, 사용자 결정이 필요한 경우 `CODE_REVIEW-local-G07.md`의 `사용자 리뷰 요청` 섹션을 채운 뒤 멈춘다.

## Roadmap Targets

- Milestone: `agent-roadmap/phase/control-plane-product-surface/milestones/cross-os-runner-bootstrap.md`
- Epic: `[bootstrap-platforms] Cross-OS bootstrap contract`
- Task id: `[oto-binary]`
- Completion mode: check-on-pass

## 배경

Unix/Windows bootstrap은 설치된 binary에 `--version`을 실행해 binary 확인 계약을 고정하려 했지만, 현재 runner CLI는 top-level `--version`을 실제 계약으로 제공하지 않는다. 더 큰 문제는 unknown command 경로가 실패 exit code를 반환하지 않아, bootstrap의 exit-code-only 검증이 help/error 출력만 보고도 성공으로 처리될 수 있다는 점이다.

## 분석 결과

### 읽은 파일

- `agent-task/m-cross-os-runner-bootstrap/04+02,03_binary_contract/code_review_local_G06_0.log`
- `apps/runner/assets/script/shell/oto_agent_bootstrap.sh`
- `apps/runner/assets/script/powershell/oto_agent_bootstrap.ps1`
- `services/core/internal/httpserver/oto_agent_bootstrap.sh`
- `services/core/internal/httpserver/oto_agent_bootstrap.ps1`
- `apps/runner/lib/cli/cli.dart`
- `apps/runner/lib/cli/commands/command_manager.dart`
- `apps/runner/bin/main.dart`
- `apps/runner/test/oto_agent_bootstrap_script_test.dart`
- `apps/runner/test/oto_agent_bootstrap_ps1_test.dart`
- `services/core/internal/httpserver/server_test.go`

### 재현 근거

`cd apps/runner && dart run bin/main.dart --version` 실행 시 `The "--version" command does not exist.`가 출력되지만 `exit_code=0`으로 종료한다. 따라서 현재 bootstrap script의 `"$install_dir/oto" --version` 성공 판정은 실제 version/health 계약을 검증하지 못한다.

### 범위 결정 근거

release asset 생성, bootstrap command API, runner registration 동작은 변경하지 않는다. 설치 binary 검증 명령과 그 명령을 검증하는 regression test만 보강한다.

### 빌드 등급

`local-G07`: CLI entrypoint와 OS별 bootstrap script가 함께 걸린 correctness follow-up이지만, 결함은 명확하고 deterministic command/test로 검증 가능하다.

## 구현 체크리스트

- [ ] 실제 runner entrypoint가 bootstrap에서 호출하는 version 또는 health command를 성공 exit code와 식별 가능한 정상 출력으로 제공한다.
- [ ] unknown top-level command가 실패 exit code를 반환하거나, bootstrap 검증이 unknown-command help/error 출력을 성공으로 오인하지 않게 한다.
- [ ] Unix/Windows bootstrap script와 Core embedded copy가 같은 검증 command를 사용하고 실패 시 설치를 중단한다.
- [ ] regression test가 실제 runner entrypoint로 선택한 검증 command를 실행해 정상 출력과 exit code를 확인하고, unknown-command 출력이 검증 성공으로 처리되지 않음을 고정한다.
- [ ] `CODE_REVIEW-local-G07.md`의 `검증 결과`에 필수 검증 명령의 실제 stdout/stderr를 붙인다.
- [ ] `CODE_REVIEW-local-G07.md`의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다.

### [REVIEW_BINARY-1] bootstrap binary 검증 명령을 실제 CLI 계약과 연결

문제: bootstrap script가 `--version`을 binary 확인 명령으로 호출하지만, runner CLI는 현재 해당 top-level 명령을 지원하지 않는다. 또한 unknown-command 경로가 exit code 0으로 끝나므로 검증이 거짓 양성으로 통과할 수 있다.

해결 방법:

- 선호안: runner CLI에 top-level `--version` 또는 동등한 version/health 계약을 추가하고, 정상 출력 형식을 테스트로 고정한다.
- 함께 보강: unknown top-level command가 실패 exit code를 반환하거나, bootstrap script가 version/health 정상 출력까지 확인해 help/error 출력을 성공으로 처리하지 않게 한다.
- OS별 bootstrap script와 `services/core/internal/httpserver/` embedded copy를 byte-identical 상태로 유지한다.

수정 후보 파일:

- `apps/runner/lib/cli/cli.dart`
- `apps/runner/lib/cli/commands/command_manager.dart`
- `apps/runner/bin/main.dart`
- `apps/runner/assets/script/shell/oto_agent_bootstrap.sh`
- `apps/runner/assets/script/powershell/oto_agent_bootstrap.ps1`
- `services/core/internal/httpserver/oto_agent_bootstrap.sh`
- `services/core/internal/httpserver/oto_agent_bootstrap.ps1`
- `apps/runner/test/oto_agent_bootstrap_script_test.dart`
- `apps/runner/test/oto_agent_bootstrap_ps1_test.dart`
- CLI regression test file if an existing suitable file is available

테스트 작성:

- 실제 runner entrypoint를 실행해 선택한 version/health command가 exit code 0과 정상 출력을 반환하는지 검증한다.
- 존재하지 않는 top-level command가 bootstrap 검증 성공 조건으로 오인되지 않도록 exit code 또는 출력 검증을 고정한다.
- Unix fake binary fixture는 version/health 성공과 실패를 계속 검증한다.
- PowerShell fixture는 선택한 command, exit code 확인, 실패 메시지, token 미노출 조건을 고정한다.

중간 검증:

- `cd apps/runner && dart run bin/main.dart --version`
- `cd apps/runner && dart test test/oto_agent_bootstrap_script_test.dart test/oto_agent_bootstrap_ps1_test.dart`

## 리뷰어를 위한 체크포인트

- `dart run bin/main.dart --version` 또는 구현자가 선택한 health command가 더 이상 unknown-command help/error로 통과하지 않는지 확인한다.
- bootstrap script가 단순 exit code만 믿어 거짓 양성을 만들지 않는지 확인한다.
- runner asset과 Core embedded shell/PS1 copy가 byte-identical인지 확인한다.
- 검증 출력에 enrollment token 또는 private release host 원문이 노출되지 않는지 확인한다.

## 최종 검증

- `git diff --check`
- `cd apps/runner && dart analyze`
- `cd apps/runner && dart test test/oto_agent_bootstrap_script_test.dart test/oto_agent_bootstrap_ps1_test.dart`
- `cd apps/runner && dart run bin/main.dart --version`
- `cd services/core && go test -count=1 ./...`

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