<!-- task=m-cross-os-runner-bootstrap/02_unix_bootstrap plan=1 tag=REVIEW_BOOTSTRAP_UNIX -->

# PLAN: Unix bootstrap 테스트 검증 회복

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

이 계획은 직전 코드리뷰 Required 문제만 해결한다. Linux/macOS shell bootstrap 구현 방향은 유지하고, 테스트가 실제 OS/arch 선택 및 실패 경로를 deterministic하게 검증하도록 보강한다. 구현 중 사용자에게 직접 질문하지 말고, 사용자 소유 결정이 필요하면 `CODE_REVIEW-cloud-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: `[unix-bootstrap]`
- Completion mode: check-on-pass

## 리뷰 실패 요약

`apps/runner/test/oto_agent_bootstrap_script_test.dart`의 새 unsupported OS 테스트가 `Process.run` 결과를 사용하지 않아 `dart analyze`가 실패한다. 또한 `UNAME_S_OVERRIDE`는 실제 script에서 읽지 않으므로 unsupported OS 경로를 만들지 못하고, 계획에 있던 Linux/macOS asset matrix 및 unsupported OS/arch 실패 검증도 text fixture 수준에 머물러 있다.

## 범위 결정 근거

필요한 수정은 bootstrap script의 제품 동작보다 테스트 하네스와 검증 증거에 한정된다. temp `PATH`에 fake `uname`/`curl`을 주입하면 현재 host OS와 네트워크에 의존하지 않고 shell script의 OS/arch 분기와 download asset 계약을 검증할 수 있다.

## 구현 체크리스트

- [ ] `oto_agent_bootstrap_script_test.dart`에 fake `uname`/`curl` 기반 helper를 추가해 host OS와 네트워크에 의존하지 않고 script를 실행한다.
- [ ] Linux/macOS x64/arm64 asset matrix를 실제 script 실행 결과로 검증한다.
- [ ] unsupported OS와 unsupported architecture가 설치 전 실패하며 exit code, stderr, download 미시작, token 미노출을 assert한다.
- [ ] `dart analyze`, bootstrap script test, agent smoke runner test 묶음, Core Go test를 실행하고 실제 stdout/stderr를 기록한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

### [REVIEW_BOOTSTRAP_UNIX-1] Deterministic OS/arch script test

문제: `Process.run` 결과가 unused라 analyzer가 실패하고, 테스트가 unsupported OS/arch 및 macOS asset 선택을 실제 script 실행으로 검증하지 않는다.

해결 방법:

- temp bin 디렉터리에 fake `uname`을 만들고 `-s`, `-m` 입력별 반환값을 테스트 케이스에서 제어한다.
- fake `curl`은 `-o` 대상 파일에 fake `oto` tarball을 복사하고, 요청된 download URL 또는 asset filename을 temp 파일에 기록한다.
- 지원 matrix는 `Linux/Darwin`과 `x86_64/amd64/aarch64/arm64` 대표 조합을 실행해 요청 asset이 `oto-linux-x64.tar.gz`, `oto-linux-arm64.tar.gz`, `oto-macos-x64.tar.gz`, `oto-macos-arm64.tar.gz`와 일치하는지 assert한다.
- unsupported OS와 unsupported arch는 `curl`이 실행되지 않았음을 함께 assert한다.

수정 파일:

- `apps/runner/test/oto_agent_bootstrap_script_test.dart`

중간 검증:

- `cd apps/runner && dart analyze`
- `cd apps/runner && dart test test/oto_agent_bootstrap_script_test.dart`

## 최종 검증

- `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`
- `cd services/core && go test ./...`

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