- Add edge node bootstrap and runtime configuration - Update observability with test coverage - Add hostsetup test and template updates - Add m-edge-local-dev-config-runtime task tracking
10 KiB
Plan - BOOTSTRAP
이 파일을 읽는 구현 에이전트에게
CODE_REVIEW-cloud-G07.md의 구현 에이전트 소유 섹션 작성은 필수다. 구현 후 검증을 실행하고 실제 출력과 구현 메모를 채운 뒤 active 파일을 그대로 두고 리뷰 준비를 보고한다. finalization은 code-review-skill 전용이다.
배경
현재 Edge config의 nodes[]는 런타임 등록 source of truth지만 사용자가 직접 YAML을 편집해야 한다. Milestone은 iop-edge node register <node-id>가 node record를 생성/갱신하고, 바로 실행 가능한 one-line bootstrap command를 출력하는 UX를 요구한다. 이 작업은 config/env 기반이 완성된 뒤 진행해야 한다.
분석 결과
읽은 파일
agent-roadmap/current.mdagent-roadmap/phase/control-plane-portal-ops/PHASE.mdagent-roadmap/phase/control-plane-portal-ops/milestones/edge-local-dev-config-runtime.mdapps/edge/cmd/edge/main.goapps/edge/cmd/edge/main_test.goapps/edge/internal/node/store.goapps/edge/internal/node/store_test.goapps/edge/internal/bootstrap/runtime.goapps/edge/internal/bootstrap/runtime_test.gopackages/config/config.gopackages/config/config_test.goconfigs/edge.yamlbin/build/field-binaries.shdocs/field-bootstrap-user-test.mddocs/field-bootstrap-work-guide.mddocs/deploy-dev.md
테스트 커버리지 공백
config checkloads YAML but does not exerciseedgenode.LoadFromConfigfrom the CLI path.edgenode.LoadFromConfigcovers duplicate token/alias/id and empty token, but not adapter/runtime semantic validation.- No
nodeornode registercommand exists. - Bootstrap scripts exist in
bin/build/field-binaries.sh, but Edge CLI does not render the one-line command from config.
심볼 참조
- 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_envmust finish first because this task needs resolved config path, advertise host, artifact URL, and Node transport address.02+01_node_register_bootstrapadds config validation and mutation.03+01,02_help_smoke_bundle_docswaits for this task because help and docs must describe the real register/bootstrap commands.
범위 결정 근거
Do not change the node transport handshake, bootstrap shell script internals, artifact build layout, Control Plane enrollment, or Node user-facing config commands here. The command may write an implementation detail config consumed by existing bootstrap scripts, but user-facing output must stay one-line and token-positional.
빌드 등급
build=cloud-G07, review=cloud-G07. This is CLI workflow, YAML mutation, token generation, bootstrap command rendering, and config validation with user-facing side effects.
구현 체크리스트
- Verify
agent-task/m-edge-local-dev-config-runtime/01_config_runtime_env/complete.logexists before implementation starts. iop-edge config checkvalidatesnodes[]id/alias/token collisions and adapter/runtime errors through the same semantics used by runtime seed.iop-edge node register <node-id>creates or updates onenodes[]record from flags/defaults without requiring manual YAML edits.- Register output ends with a single user-facing bootstrap command in
curl -fsSL <complete-url> | bash -s <token>form and does not require namedIOP_*=parameters. - Token generation/upsert behavior is deterministic in tests and does not leak full token in extra diagnostic output.
- CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.
의존 관계 및 구현 순서
Directory dependency is 02+01_node_register_bootstrap: wait for agent-task/m-edge-local-dev-config-runtime/01_config_runtime_env/complete.log. Do not add hidden dependencies beyond that.
[BOOTSTRAP-1] Config Check Uses Runtime Node Validation
문제
apps/edge/cmd/edge/main.go only calls config.LoadEdge, while apps/edge/internal/node/store.go is where duplicate token/alias/id and empty token are rejected for runtime.
Before:
// apps/edge/cmd/edge/main.go:153
if _, err := config.LoadEdge(cfgFile); err != nil {
return fmt.Errorf("load config: %w", err)
}
해결 방법
After loading the resolved config, call an edge CLI validator that delegates node seed validation to edgenode.LoadFromConfig(cfg.Nodes) and adds adapter/runtime checks. Keep validation in apps/edge/cmd/edge or apps/edge/internal/node rather than packages/config to avoid importing app internals into common packages.
수정 파일 및 체크리스트
apps/edge/cmd/edge/main.go: addvalidateEdgeConfigcall inconfig check.apps/edge/cmd/edge/main_test.go: add CLI tests for duplicate token/id/alias and invalid adapter/runtime flags.apps/edge/internal/node/store.go: add semantic validation only if it belongs to runtime seed; otherwise keep CLI-only validation in command package.apps/edge/internal/node/store_test.go: extend only if store behavior changes.
테스트 작성
Write TestConfigCheckRejectsDuplicateNodeToken and at least one adapter/runtime invalid config test.
중간 검증
go test -count=1 ./apps/edge/cmd/edge ./apps/edge/internal/node
Expected: pass; cache output is not acceptable.
[BOOTSTRAP-2] Node Register Upserts Edge YAML
문제
docs/field-bootstrap-user-test.md says Node definitions are made with iop-edge node register, but apps/edge/cmd/edge/main.go has no node command.
Before:
// apps/edge/cmd/edge/main.go:35
root.AddCommand(serveCmd(), consoleCmd(), versionCmd(), configCmd(), setupCmd())
해결 방법
Add nodeCmd() with register subcommand. Load resolved edge config and YAML, upsert by id, default alias to id, generate token if not provided, and support initial flags:
iop-edge node register <node-id>
--alias <alias>
--token <token>
--adapter ollama|cli
--ollama-base-url <url>
--ollama-context-size <n>
--runtime-concurrency <n>
--workspace-root <path>
Use gopkg.in/yaml.v3 already present in apps/edge/cmd/edge/main.go for writing. Keep output concise: write/update line plus final bootstrap command.
수정 파일 및 체크리스트
apps/edge/cmd/edge/main.go: add node/register command, token generator injection for tests, YAML upsert helpers.apps/edge/cmd/edge/main_test.go: test create, update, generated token, explicit token, adapter flags, and no manualnodes[]edit path.packages/config/config.go: add fields only if BOOTSTRAP-2 needs config surface not already added by CONFIG-2.configs/edge.yaml: do not add field tokens or host-specific generated values.
테스트 작성
Write temp-file CLI tests that run config init --output, then node register, then config check. Assert exactly one node record after update and that generated token is present in YAML and bootstrap output.
중간 검증
go test -count=1 ./apps/edge/cmd/edge ./packages/config
Expected: pass; cache output is not acceptable.
[BOOTSTRAP-3] Bootstrap Command Rendering
문제
bin/build/field-binaries.sh generates target-specific bootstrap scripts, but docs/field-bootstrap-user-test.md expects Edge CLI to output the complete one-line command.
Before:
# docs/field-bootstrap-user-test.md:96
curl -fsSL http://toki-labs.com:18080/bootstrap/node-darwin-arm64.sh | bash -s <generated-token>
해결 방법
Render command from CONFIG-2 effective artifact base URL and default platform target. Provide flags on node register:
--target darwin-arm64
--artifact-base-url <url>
Default target can be current host GOOS-GOARCH for local dev, but tests should pass explicit --target darwin-arm64. The final visible command must be exactly one line with completed URL and token positional arg. Do not output IOP_ARTIFACT_BASE_URL=, IOP_EDGE_ADDR=, or IOP_NODE_TOKEN= in the default path.
수정 파일 및 체크리스트
apps/edge/cmd/edge/main.go: add bootstrap command renderer helper and register output.apps/edge/cmd/edge/main_test.go: assert one-line command, complete URL, token positional arg, and absence of named env parameters.docs/field-bootstrap-work-guide.md: no change in this subtask unless a field constant changes; defer broad docs to subtask 03.
테스트 작성
Write TestNodeRegisterPrintsOneLineBootstrapCommand and TestNodeRegisterUsesConfiguredArtifactBaseURL.
중간 검증
go test -count=1 ./apps/edge/cmd/edge
Expected: pass; cache output is not acceptable.
수정 파일 요약
| 파일 | 항목 |
|---|---|
apps/edge/cmd/edge/main.go |
BOOTSTRAP-1, BOOTSTRAP-2, BOOTSTRAP-3 |
apps/edge/cmd/edge/main_test.go |
BOOTSTRAP-1, BOOTSTRAP-2, BOOTSTRAP-3 |
apps/edge/internal/node/store.go |
BOOTSTRAP-1 |
apps/edge/internal/node/store_test.go |
BOOTSTRAP-1 |
packages/config/config.go |
BOOTSTRAP-2 |
packages/config/config_test.go |
BOOTSTRAP-2 |
최종 검증
test -f agent-task/m-edge-local-dev-config-runtime/01_config_runtime_env/complete.log
go test -count=1 ./apps/edge/cmd/edge ./apps/edge/internal/node ./packages/config
tmp="$(mktemp -d)" && go build -o "$tmp/iop-edge" ./apps/edge/cmd/edge && (cd "$tmp" && ./iop-edge config init --force && ./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 config check)
Expected: predecessor exists; tests pass; temp command creates/updates edge.yaml, prints one final curl -fsSL http://toki-labs.com:18080/bootstrap/node-darwin-arm64.sh | bash -s <token> command, and config check passes.
모든 코드 변경 완료 후 반드시 CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 채운다. 이 파일 작성이 구현의 마지막 단계다.