<!-- task=m-edge-local-dev-config-runtime/03+01,02_help_smoke_bundle_docs plan=0 tag=UX -->

# Plan - UX

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

`CODE_REVIEW-cloud-G07.md`의 구현 에이전트 소유 섹션 작성은 필수다. 구현 후 검증을 실행하고 실제 출력과 구현 메모를 채운 뒤 active 파일을 그대로 두고 리뷰 준비를 보고한다. finalization은 code-review-skill 전용이다.

## 배경

After config/env and node register exist, the Milestone still needs the user-facing loop to be discoverable from `iop-edge help` and runnable from a clean bundle. Current docs already describe `iop-edge env`, `node register`, `nodes list`, and `smoke openai`, but the CLI does not yet expose all of that behavior. This subtask closes the official UX and verification layer without making `bin/*` or Node config commands the default user path.

## 분석 결과

### 읽은 파일

- `agent-roadmap/current.md`
- `agent-roadmap/phase/control-plane-portal-ops/PHASE.md`
- `agent-roadmap/phase/control-plane-portal-ops/milestones/edge-local-dev-config-runtime.md`
- `apps/edge/cmd/edge/main.go`
- `apps/edge/cmd/edge/main_test.go`
- `apps/edge/README.md`
- `apps/node/cmd/node/main.go`
- `apps/node/cmd/node/main_test.go`
- `packages/config/config.go`
- `packages/config/config_test.go`
- `bin/build/field-binaries.sh`
- `Makefile`
- `docs/field-bootstrap-user-test.md`
- `docs/field-bootstrap-work-guide.md`
- `docs/deploy-dev.md`

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

- Root/config/setup help has basic command presence tests, but no test asserts official user-flow text.
- `nodes list` and `smoke openai` commands do not exist.
- Existing `make test-e2e` is an auxiliary repo smoke and does not verify clean bundle UX.
- Docs contain future commands that are not yet synchronized with actual CLI output.

### 심볼 참조

- none. No rename/remove is planned.

### 분할 판단

Split decision policy was evaluated before choosing plan files. Shared task group: `agent-task/m-edge-local-dev-config-runtime/`.
- `01_config_runtime_env` provides env/config/log/address behavior.
- `02+01_node_register_bootstrap` provides register/bootstrap behavior.
- `03+01,02_help_smoke_bundle_docs` depends on both so help, smoke, docs, and bundle verification describe implemented behavior rather than placeholders.

### 범위 결정 근거

Do not add Control Plane enrollment, production signing, mTLS, credential rotation, or a second dev deploy binary. Do not make `bin/edge.sh`, `bin/node.sh`, or `iop-node serve --config` official user documentation. Keep `make test-e2e` as auxiliary verification only.

### 빌드 등급

build=`cloud-G07`, review=`cloud-G07`. This is terminal UX, help output, smoke command, docs, and clean-bundle verification work.

## 구현 체크리스트

- [ ] Verify `agent-task/m-edge-local-dev-config-runtime/01_config_runtime_env/complete.log` and `agent-task/m-edge-local-dev-config-runtime/02+01_node_register_bootstrap/complete.log` exist before implementation starts.
- [ ] `iop-edge help`, `iop-edge config --help`, `iop-edge node --help`, `iop-edge node register --help`, and `iop-edge smoke --help` expose the official flow without requiring docs.
- [ ] `iop-edge nodes list` reads configured nodes and, when offline, clearly distinguishes configured nodes from connected runtime nodes.
- [ ] `iop-edge smoke openai --model <model>` verifies OpenAI-compatible health/models/chat against the configured or provided URL and reports actionable failures.
- [ ] Docs and README surfaces match implemented commands and do not present `bin/*`, dev deploy binaries, Node config edits, or `iop-node serve --config` as the official user path.
- [ ] Clean temp bundle verification builds binaries, initializes config, registers a node, checks config/env/help, and performs at least the non-network parts deterministically; network/full-cycle blockers are explicitly recorded.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

## 의존 관계 및 구현 순서

Directory dependency is `03+01,02_help_smoke_bundle_docs`: wait for both `agent-task/m-edge-local-dev-config-runtime/01_config_runtime_env/complete.log` and `agent-task/m-edge-local-dev-config-runtime/02+01_node_register_bootstrap/complete.log`. Do not add hidden dependencies beyond the directory name.

### [UX-1] Help Discovery

#### 문제

[docs/field-bootstrap-user-test.md](/config/workspace/iop/docs/field-bootstrap-user-test.md:31) expects users to discover a sequence from `iop-edge`, but [apps/edge/cmd/edge/main.go](/config/workspace/iop/apps/edge/cmd/edge/main.go:29) root command has only a short description and no flow-level help.

Before:

```go
// apps/edge/cmd/edge/main.go:29
root := &cobra.Command{
    Use:   "edge",
    Short: "IOP Edge — execution group controller",
}
```

#### 해결 방법

Add concise `Long`/`Example` text to root and relevant subcommands. Help must show this official order: `config init`, `env`, `node register`, `config check`, `serve`, `nodes list`, `smoke openai`. Include required/optional flag descriptions for `node register` and `smoke openai`.

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

- [ ] `apps/edge/cmd/edge/main.go`: add help text to root/config/node/register/smoke commands.
- [ ] `apps/edge/cmd/edge/main_test.go`: add help output assertions for official flow and absence of `bin/edge.sh`, `bin/node.sh`, and `dev-deploy`.

#### 테스트 작성

Write `TestHelpDiscoversEdgeLocalDevFlow` and focused subcommand help tests.

#### 중간 검증

```bash
go test -count=1 ./apps/edge/cmd/edge
```

Expected: pass; cache output is not acceptable.

### [UX-2] Nodes List And OpenAI Smoke

#### 문제

[docs/field-bootstrap-user-test.md](/config/workspace/iop/docs/field-bootstrap-user-test.md:146) documents `./iop-edge nodes list`, and [docs/field-bootstrap-user-test.md](/config/workspace/iop/docs/field-bootstrap-user-test.md:152) documents `./iop-edge smoke openai --model gemma4:26b`, but there are no commands for either.

Before:

```text
./iop-edge nodes list
./iop-edge smoke openai --model gemma4:26b
```

#### 해결 방법

Add:

```text
iop-edge nodes list
iop-edge smoke openai --model <model> [--base-url <url>] [--prompt <text>] [--timeout <duration>]
```

`nodes list` should load config and print configured nodes; connected runtime count can be `offline` unless a later native API exists. `smoke openai` should call `/healthz`, `/v1/models`, and non-streaming `/v1/chat/completions` using `net/http`. If config OpenAI listen is `0.0.0.0:8080`, local smoke should use `127.0.0.1:8080` unless `--base-url` is set. Use exact exit statuses via returned errors.

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

- [ ] `apps/edge/cmd/edge/main.go`: add `nodes` and `smoke` command groups.
- [ ] `apps/edge/cmd/edge/main_test.go`: test `nodes list` output from temp config and `smoke openai` against `httptest.Server`.
- [ ] `packages/config/config.go`: no change unless prior subtasks added URL fields that need reuse.

#### 테스트 작성

Write tests with `httptest.Server` for successful health/models/chat and failure on empty content or non-200. Avoid real network in unit tests.

#### 중간 검증

```bash
go test -count=1 ./apps/edge/cmd/edge
```

Expected: pass; cache output is not acceptable.

### [UX-3] Docs And Clean Bundle Verification

#### 문제

[docs/deploy-dev.md](/config/workspace/iop/docs/deploy-dev.md:104) still says dev initially uses repo `configs/edge.yaml`, while this Milestone moves source of truth to bundle-local `edge.yaml`. [docs/deploy-dev.md](/config/workspace/iop/docs/deploy-dev.md:558) lists implemented CLI commands but will be stale once this Milestone lands.

Before:

```text
// docs/deploy-dev.md:561
iop-edge serve
iop-edge console
iop-edge setup
iop-edge config print
iop-edge config check
iop-edge version
```

#### 해결 방법

Update docs to match actual CLI after UX-1/UX-2. Keep `docs/field-bootstrap-user-test.md` as the user-facing flow, `docs/field-bootstrap-work-guide.md` as worker/runbook details, and `docs/deploy-dev.md` as deployment reference. Add clean bundle verification commands to the review output, not a new official script, unless Makefile already has a suitable target and the team prefers a target.

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

- [ ] `docs/field-bootstrap-user-test.md`: align commands, outputs, and troubleshooting with implemented CLI.
- [ ] `docs/deploy-dev.md`: replace repo `configs/edge.yaml` default language with bundle-local `edge.yaml` flow and update command list.
- [ ] `apps/edge/README.md`: update Edge CLI section.
- [ ] `Makefile`: leave unchanged unless a tiny deterministic helper target is clearly better than repeating command lines.

#### 테스트 작성

Docs-only assertions should be `rg --sort path` checks in final verification. Do not add brittle line-number tests for docs.

#### 중간 검증

```bash
rg --sort path "bin/edge.sh|bin/node.sh|dev deploy binary|iop-node serve --config" docs/field-bootstrap-user-test.md docs/deploy-dev.md apps/edge/README.md
```

Expected: either no output, or only explicit "not official/default path" warnings.

## 수정 파일 요약

| 파일 | 항목 |
|---|---|
| `apps/edge/cmd/edge/main.go` | UX-1, UX-2 |
| `apps/edge/cmd/edge/main_test.go` | UX-1, UX-2 |
| `docs/field-bootstrap-user-test.md` | UX-3 |
| `docs/deploy-dev.md` | UX-3 |
| `docs/field-bootstrap-work-guide.md` | UX-3 |
| `apps/edge/README.md` | UX-3 |
| `Makefile` | UX-3, only if a deterministic helper target is chosen |

## 최종 검증

```bash
test -f agent-task/m-edge-local-dev-config-runtime/01_config_runtime_env/complete.log
test -f agent-task/m-edge-local-dev-config-runtime/02+01_node_register_bootstrap/complete.log
```

```bash
go test -count=1 ./apps/edge/cmd/edge ./packages/config
```

```bash
tmp="$(mktemp -d)" && go build -o "$tmp/iop-edge" ./apps/edge/cmd/edge && go build -o "$tmp/iop-node" ./apps/node/cmd/node && (cd "$tmp" && ./iop-edge config init --force && ./iop-edge env && ./iop-edge node register node-silicon-ollama --adapter ollama --ollama-base-url http://127.0.0.1:11434 --target darwin-arm64 --artifact-base-url http://toki-labs.com:18080 && ./iop-edge nodes list && ./iop-edge config check && ./iop-edge help && ./iop-edge config --help && ./iop-edge node --help && ./iop-edge node register --help && ./iop-edge smoke --help)
```

```bash
rg --sort path "bin/edge.sh|bin/node.sh|dev deploy binary|iop-node serve --config" docs/field-bootstrap-user-test.md docs/deploy-dev.md apps/edge/README.md
```

Expected: predecessor files exist; tests pass; clean bundle command completes non-network commands; help output shows official flow; docs search shows no default-user-path references except explicit negative warnings.

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