# PLAN: Windows PowerShell bootstrap command 인자 전달 수정 ## 이 파일을 읽는 구현 에이전트에게 이 계획은 직전 코드리뷰 `code_review_cloud_G06_0.log`의 Required 이슈만 해결한다. 구현 중 사용자 결정이 필요하면 채팅으로 질문하지 말고 동반 `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: `[core-command]` - Completion mode: check-on-pass ## 실패 원인 `services/core/internal/httpserver/runner_handlers.go`의 Windows command는 `powershell -ExecutionPolicy Bypass -Command "irm ... | iex" -- --server-url ...` 형태다. 이 형태는 다운로드한 script를 실행하더라도 `--server-url`, `--agent-id`, `--enrollment-token`, `--release-base-url` 인자를 script invocation에 넘기는 구조가 아니다. Windows bootstrap command 계약은 script URL과 필수 bootstrap 인자를 함께 전달해야 한다. ## 범위 결정 근거 이번 후속은 Core command template과 해당 Go 테스트만 수정한다. PowerShell bootstrap script asset 자체, `/bootstrap/oto-agent.ps1` serving route, OS별 binary install 구현은 후속 split 작업 범위로 둔다. ## 구현 체크리스트 - [ ] Windows bootstrap command가 다운로드한 PowerShell script를 scriptblock으로 실행하고 `--server-url`, `--agent-id`, `--enrollment-token`, `--release-base-url`을 같은 `-Command` 표현식 안에서 전달하도록 수정한다. - [ ] PowerShell escaping helper/command template이 single quote, semicolon, `$()`가 포함된 runner_id/token을 실행하지 않고 인자로 보존하도록 테스트를 갱신한다. - [ ] 기존 no-target/Linux/macOS shell command와 invalid target 400/token 비노출 계약이 유지되는지 확인한다. - [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다. ### [REVIEW_API-1] Windows command가 script 인자를 실제 invocation에 전달하도록 수정 문제: PowerShell command의 인자가 `-Command` 문자열 밖에 붙어 있어 다운로드된 script의 `$args` 또는 parameter binding으로 전달된다고 볼 수 없다. 해결 방법: - `runner_handlers.go`의 Windows branch를 다운로드 script를 scriptblock으로 만든 뒤 그 scriptblock invocation에 bootstrap 인자를 붙이는 형태로 바꾼다. - 예시는 `powershell -ExecutionPolicy Bypass -Command "& ([scriptblock]::Create((irm ))) -- --server-url --agent-id --enrollment-token --release-base-url "` 같은 구조다. 실제 문법은 테스트 가능하고 quoting이 안전한 형태로 고정한다. - `powershellEscape`가 이 command template에서 안전한지 다시 점검하고, single quote를 포함한 token이 PowerShell 코드로 실행되지 않고 literal argument로 남도록 한다. - `server_test.go`의 Windows expected command와 malicious field 케이스를 새 구조로 갱신한다. 테스트는 인자들이 `-Command` 표현식 내부의 scriptblock invocation 뒤에 위치하는지 드러나야 한다. 수정 파일 및 체크리스트: - `services/core/internal/httpserver/runner_handlers.go` - `services/core/internal/httpserver/server_test.go` 테스트 작성: - Windows target expected command를 새 scriptblock invocation 구조로 갱신한다. - malicious runner_id/token 케이스가 literal quoting을 보존하는지 유지한다. - no-target, linux, macos, invalid target 케이스는 회귀로 유지한다. 중간 검증: - `cd services/core && go test ./...` ## 최종 검증 - `cd services/core && go test ./...` - `cd apps/runner && dart analyze` ## 리뷰 포인트 - Windows command가 다운로드 script 실행과 bootstrap 인자 전달을 같은 PowerShell `-Command` 표현식 안에서 수행하는지 확인한다. - runner id/token escaping이 PowerShell code injection으로 바뀌지 않는지 확인한다. - 기존 Linux/macOS/default target 계약이 변하지 않았는지 확인한다.