<!-- task=edge_bootstrap plan=1 tag=REVIEW_API -->

# Edge Bootstrap Linux Script 후속 수정 계획

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

`CODE_REVIEW-cloud-G07.md`의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채우는 것이 필수다. 구현 후 검증을 실행하고, 실제 notes/output을 채우고, active 파일은 그대로 둔 채 리뷰 준비 완료를 보고한다. 최종 판정, log rename, `complete.log`, archive 이동은 code-review-skill 전용이다.

## 배경

첫 리뷰(`code_review_cloud_G07_0.log`)에서 Linux bootstrap script가 pid 파일 위치와 release URL 보안 계약을 충족하지 못하는 Required 문제가 확인되었다. 이 계획은 기존 script/test 범위 안에서 해당 두 계약만 좁게 수정한다.

## 분석 결과

### 읽은 파일

- `agent-task/edge_bootstrap/plan_cloud_G07_0.log`
- `agent-task/edge_bootstrap/code_review_cloud_G07_0.log`
- `agent-ops/roadmap/milestones/edge-bootstrap-contract.md`
- `agent-ops/rules/project/domain/cli/rules.md`
- `agent-ops/rules/project/domain/framework/rules.md`
- `assets/script/shell/oto_agent_bootstrap.sh`
- `test/oto_agent_bootstrap_script_test.dart`

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

- custom `--config-path` 사용 시 pid 파일이 `~/.oto/agent/oto-agent.pid`에 유지되는지 검증하지 않는다.
- HTTP `--release-base-url`이 다운로드 전에 실패하는지 검증하지 않는다.

### 심볼 참조

- renamed/removed symbols: none.
- 기존 Dart public API 변경은 없다.

### 범위 결정 근거

- 포함: `assets/script/shell/oto_agent_bootstrap.sh`, `test/oto_agent_bootstrap_script_test.dart`.
- 제외: Edge 서버 API, 실제 `oto agent run` CLI 구현, checksum/signature/fingerprint/systemd user service.
- 제외: 로드맵 문서 수정. 이번 후속 작업은 리뷰 Required 항목만 처리한다.

### 빌드 등급

- build lane: `cloud-G07`
- review lane: `cloud-G07`
- 근거: shell/CLI workflow, installer orchestration, pid/log/URL validation 계약을 다루는 terminal-agent 성격이다.

## 구현 체크리스트

- [ ] [REVIEW_API-1] pid 파일을 표준 agent 상태 경로에 기록하도록 수정한다.
- [ ] [REVIEW_API-2] release base URL HTTPS 검증과 회귀 테스트를 추가한다.
- [ ] 모든 중간 검증과 최종 검증을 실행하고 실제 출력을 `CODE_REVIEW-cloud-G07.md`에 기록한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

### [REVIEW_API-1] pid 파일 표준 위치 수정

#### 문제

`assets/script/shell/oto_agent_bootstrap.sh:134`가 pid를 `config_dir` 아래에 기록한다. 계획과 Milestone은 pid 파일 위치를 `~/.oto/agent/oto-agent.pid`로 고정했으므로, custom `--config-path`를 사용하면 표준 pid 위치가 깨진다.

#### 해결 방법

`config_dir`와 별개로 agent 상태 디렉터리와 pid 경로를 둔다.

Before:

```bash
config_dir=$(dirname "$config_path")
...
echo "$pid" > "$config_dir/oto-agent.pid"
```

After:

```bash
config_dir=$(dirname "$config_path")
agent_state_dir="${HOME}/.oto/agent"
pid_path="${agent_state_dir}/oto-agent.pid"
mkdir -p "$config_dir"
mkdir -p "$agent_state_dir"
...
echo "$pid" > "$pid_path"
```

`--config-path`는 config 파일 위치만 바꾸고 pid 파일 계약은 바꾸지 않는다. 출력 메시지가 pid 위치를 안내한다면 `$pid_path`를 사용한다.

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

- [ ] `assets/script/shell/oto_agent_bootstrap.sh`에서 pid 경로를 `config_dir` 파생값이 아닌 표준 agent 상태 경로로 분리한다.
- [ ] `test/oto_agent_bootstrap_script_test.dart`에 custom `--config-path` 사용 시 pid 파일이 `$HOME/.oto/agent/oto-agent.pid`에 생기는 검증을 추가한다.
- [ ] test fixture는 fake `curl`과 local tar archive를 사용해 외부 네트워크와 실제 OTO 실행에 의존하지 않는다.

#### 테스트 작성

`test/oto_agent_bootstrap_script_test.dart`에 process 기반 회귀 테스트를 추가한다.

- 임시 `HOME`을 만든다.
- fake release archive에 실행 가능한 `oto` 파일을 넣는다.
- fake `curl`을 `PATH` 앞에 두어 archive를 `-o` 경로로 복사하게 한다.
- bootstrap script를 custom `--config-path`와 함께 실행한다.
- `$HOME/.oto/agent/oto-agent.pid`가 존재하고 custom config 디렉터리 아래 `oto-agent.pid`가 존재하지 않음을 확인한다.

#### 중간 검증

```bash
dart test test/oto_agent_bootstrap_script_test.dart
```

기대 결과: 모든 테스트 통과.

### [REVIEW_API-2] release base URL HTTPS 검증 추가

#### 문제

`assets/script/shell/oto_agent_bootstrap.sh:96`이 `release_base_url`을 그대로 다운로드 URL로 사용한다. Milestone의 MVP 차단 조건은 release base URL이 HTTPS여야 한다.

#### 해결 방법

필수 인자 누락 검증 이후, arch 선택과 다운로드 전에 HTTPS scheme을 검증한다.

Before:

```bash
download_url="${release_base_url}/${asset_name}"
```

After:

```bash
case "$release_base_url" in
  https://*) ;;
  *)
    echo "Error: --release-base-url must use https://" >&2
    exit 1
    ;;
esac
```

검증은 다운로드 전에 수행되어야 하며, 실패 메시지에 enrollment token을 포함하지 않는다.

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

- [ ] `assets/script/shell/oto_agent_bootstrap.sh`에 `release_base_url` HTTPS 검증을 추가한다.
- [ ] HTTP `--release-base-url`이 다운로드 전에 실패하는 테스트를 추가한다.
- [ ] 실패 출력에 token 값이 포함되지 않는지 테스트한다.

#### 테스트 작성

`test/oto_agent_bootstrap_script_test.dart`에 `Process.run` 기반 테스트를 추가한다. 필수 인자는 모두 제공하되 `--release-base-url http://...`을 넘기고, exit code가 0이 아니며 stderr가 HTTPS 요구를 설명하고 stdout에 다운로드 메시지가 없음을 검증한다.

#### 중간 검증

```bash
dart test test/oto_agent_bootstrap_script_test.dart
```

기대 결과: 모든 테스트 통과.

## 수정 파일 요약

| 파일 | 항목 |
|------|------|
| `assets/script/shell/oto_agent_bootstrap.sh` | REVIEW_API-1, REVIEW_API-2 |
| `test/oto_agent_bootstrap_script_test.dart` | REVIEW_API-1, REVIEW_API-2 |

## 최종 검증

```bash
bash -n assets/script/shell/oto_agent_bootstrap.sh
dart test test/oto_agent_bootstrap_script_test.dart
dart analyze
rg --sort path -n "release_base_url|https://|oto-agent.pid|pid_path|config_dir" assets/script/shell/oto_agent_bootstrap.sh test/oto_agent_bootstrap_script_test.dart
```

기대 결과: 각 명령 exit code 0. `dart test`는 fresh 실행 출력이어야 하며 캐시 출력으로 대체하지 않는다. `rg`는 HTTPS 검증과 표준 pid 경로가 script/test 양쪽에서 확인되어야 한다.

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