<!-- task=m-runtime-reconnect-config-refresh/07+01,03,04,05,06_field_docs_smoke plan=1 tag=REVIEW_TEST -->

# Plan - REVIEW_TEST

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

`CODE_REVIEW-cloud-G08.md`의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 반드시 채운다. 검증 명령을 실행하고 실제 stdout/stderr를 붙여 넣은 뒤 active 파일을 그대로 두고 review ready로 보고한다. 최종 판정, log rename, `complete.log`, archive 이동은 code-review-skill 전용이다. 선택된 Milestone `구현 잠금 > 결정 필요` 항목이 실구현을 막을 때만 review stub의 `사용자 리뷰 요청` 섹션을 채우고 멈춘다. 외부 환경/secret/service blocker, 일반 범위 조정, 증거 공백은 사용자 리뷰가 아니라 검증 결과나 후속 plan으로 기록한다. 구현 중 사용자에게 직접 질문하거나 선택지를 제시하거나 `request_user_input`을 호출하지 않는다.

## 배경

이전 review loop는 field smoke를 닫지 못했다. 원격 dev-runtime의 CP/Edge/Node 프로세스가 모두 내려가 있었고, plan의 검증 명령은 실제 dev-runtime binary 경로(`build/dev-runtime/bin/edge`)를 찾지 못했다. SDD S16/S17/S18은 여전히 `field-reconnect`, `field-refresh`, `docs` 완료 evidence를 요구하므로, 이번 follow-up은 검증 계약과 dev-runtime 기준을 바로잡고 실제 field evidence를 다시 수집한다.

## 사용자 리뷰 요청 흐름

선택된 Milestone lock 결정만 active review stub의 `사용자 리뷰 요청` 섹션에 기록한다. 구현 중 직접 사용자에게 묻지 말고, code-review가 해당 요청을 검증한 뒤 실제 `USER_REVIEW.md` 작성 여부를 결정한다.

## Roadmap Targets

- Milestone: `agent-roadmap/phase/update-plane-self-update-foundation/milestones/runtime-reconnect-config-refresh.md`
- Task ids:
  - `field-reconnect`: `toki-labs.com` dev-runtime에서 Edge restart 후 GX10 Linux Node와 OneXPlayer Windows Node가 bootstrap 재실행 없이 재접속한다.
  - `field-refresh`: `gx10-vllm=4`, `onexplayer-lemonade=3` capacity 변경을 refresh로 반영하고 Edge process restart 없이 `qwen3.6:35b` 동시 4개 요청이 성공한다.
  - `docs`: bootstrap/reconnect/refresh 운영 방법과 제한 사항이 `apps/edge/README.md`, `docs/edge-local-dev-guide.md`, agent-test field 기준에 반영된다.
- Completion mode: check-on-pass

## Archive Evidence Snapshot

- Prior active task: `agent-task/m-runtime-reconnect-config-refresh/07+01,03,04,05,06_field_docs_smoke`
- Archived plan log: `agent-task/m-runtime-reconnect-config-refresh/07+01,03,04,05,06_field_docs_smoke/plan_cloud_G08_0.log`
- Archived review log: `agent-task/m-runtime-reconnect-config-refresh/07+01,03,04,05,06_field_docs_smoke/code_review_cloud_G08_0.log`
- Verdict: FAIL
- Required summary:
  - S16 `field-reconnect` evidence missing. TEST-1 exited 1 before restart/reconnect evidence.
  - S17 `field-refresh` evidence missing. TEST-2 exited 1 before config check, refresh dry-run/apply, health/models, concurrent requests.
  - Plan verification command searched `iop-edge`, `./build/bin/iop-edge`, `./build/dev-runtime/iop-edge`; actual remote dev-runtime binary is `build/dev-runtime/bin/edge`.
  - `docs/edge-local-dev-guide.md` and agent-test field criteria need to align with the actual dev-runtime binary/config.
  - Final evidence check failed because `/tmp/iop-field-evidence/reconnect-after-status.json`, `reconnect-after-tcp.txt`, `refresh-apply.json`, and `refresh-concurrent-4.jsonl` were missing.
- Affected files:
  - `docs/edge-local-dev-guide.md`
  - `agent-test/local/edge-smoke.md`
  - `agent-test/local/rules.md` if actual field criteria changed
  - `CODE_REVIEW-cloud-G08.md`
- Verification evidence from prior loop:
  - Remote read-only recheck confirmed `build/dev-runtime/bin/edge=yes`, `command -v iop-edge` empty, `build/bin/iop-edge=no`, `build/dev-runtime/iop-edge=no`.
  - Remote ports `18001`, `18083`, `18084`, `19093` were closed.
  - Remote `build/dev-runtime/edge.yaml` had target capacities but no `refresh:` block.
  - Remote `build/dev-runtime` contains `bin/control-plane`, `bin/edge`, `bin/iop-node`, `control-plane.yaml`, `edge.yaml`, `node-codex.yaml`, `node-gx10-vllm.yaml`, and `node-onexplayer-lemonade.yaml`.
- Roadmap carryover: `field-reconnect`, `field-refresh`, and `docs` remain incomplete until this follow-up PASS writes `Roadmap Completion`.
- Narrow archive reread allowed if needed: only the two archived logs listed above.

## 분석 결과

### 읽은 파일

- `agent-roadmap/current.md`
- `agent-roadmap/phase/update-plane-self-update-foundation/milestones/runtime-reconnect-config-refresh.md`
- `agent-roadmap/sdd/update-plane-self-update-foundation/runtime-reconnect-config-refresh/SDD.md`
- `agent-ops/rules/project/rules.md`
- `agent-ops/rules/common/rules-roadmap.md`
- `agent-ops/rules/project/domain/edge/rules.md`
- `agent-ops/rules/project/domain/testing/rules.md`
- `agent-ops/skills/common/router.md`
- `agent-ops/skills/common/code-review/SKILL.md`
- `agent-ops/skills/common/plan/SKILL.md`
- `agent-ops/skills/common/_templates/implementation-user-review-request-section.md`
- `agent-test/local/rules.md`
- `agent-test/local/edge-smoke.md`
- `Makefile`
- `apps/edge/README.md`
- `docs/edge-local-dev-guide.md`
- `apps/edge/internal/edgecmd/config.go`
- `apps/node/cmd/node/main.go`
- `apps/control-plane/cmd/control-plane/main.go`
- `agent-task/m-runtime-reconnect-config-refresh/07+01,03,04,05,06_field_docs_smoke/plan_cloud_G08_0.log`
- `agent-task/m-runtime-reconnect-config-refresh/07+01,03,04,05,06_field_docs_smoke/code_review_cloud_G08_0.log`

### SDD 기준

- SDD: `agent-roadmap/sdd/update-plane-self-update-foundation/runtime-reconnect-config-refresh/SDD.md`
- 상태: `[승인됨]`, SDD 잠금 해제, 사용자 리뷰 없음.
- Target scenarios:
  - S16 -> `field-reconnect`: Edge restart 후 bootstrap 재실행 없이 mac-codex, GX10, OneXPlayer Node 3개 연결 회복.
  - S17 -> `field-refresh`: `gx10-vllm=4`, `onexplayer-lemonade=3` refresh apply 후 Edge restart 없이 `qwen3.6:35b` 동시 4개 요청 성공.
  - S18 -> `docs`: docs diff와 agent-test field rule diff.
- Evidence Map:
  - S16 evidence: remote dev field status와 TCP connection evidence.
  - S17 evidence: remote dev 4 concurrent OpenAI-compatible requests와 refresh result evidence.
  - S18 evidence: docs diff와 agent-test field rule diff.
- 이 follow-up은 S16/S17 evidence 파일을 실제로 생성하고, S18 문서/agent-test 기준이 그 evidence와 모순되지 않게 갱신한다.

### 테스트 환경 규칙

- `test_env=local`.
- `agent-test/local/rules.md`는 field/bootstrap, 외부 runtime evidence를 원격 runner `ssh toki@toki-labs.com`의 `/Users/toki/agent-work/iop-dev` 기준으로 수행하라고 한다.
- Matched profile: `agent-test/local/edge-smoke.md`.
- 적용 기준: dev-runtime config `build/dev-runtime/edge.yaml`, CP status `http://127.0.0.1:18001`, Edge OpenAI-compatible `http://toki-labs.com:18083/v1`, Edge-Node TCP `toki-labs.com:18084`, model alias `qwen3.6:35b`, capacity `gx10-vllm=4`, `onexplayer-lemonade=3`.
- `<확인 필요>` 값 없음.
- Remote runtime artifact 기준은 actual file listing을 우선한다. 현재 remote에는 `build/dev-runtime/bin/edge`가 있고 `iop-edge` 이름은 없다.

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

- `field-reconnect`: unit/integration은 선행 task에서 닫혔지만 S16 remote field evidence가 없다.
- `field-refresh`: unit/integration은 선행 task에서 닫혔지만 S17 remote refresh apply와 동시 4개 요청 evidence가 없다.
- `docs`: stale wording search는 통과했지만, field guide와 agent-test command가 actual dev-runtime binary/config와 불일치한다.

### 심볼 참조

- none. 이 follow-up은 Go symbol rename/remove를 하지 않는다.

### 분할 판단

- split decision policy는 이미 적용된 Milestone split subtask를 유지한다.
- 공유 task group: `m-runtime-reconnect-config-refresh`.
- 선택 subtask: `07+01,03,04,05,06_field_docs_smoke`.
- 이 follow-up은 같은 active subtask에서 prior FAIL을 재시도한다. 새 subtask를 만들지 않는다.
- Direct predecessors `01`, `03`, `04`, `05`, `06`는 prior plan에서 archive complete.log로 충족 확인됐다. 이번 follow-up은 그 선행 결과를 다시 수정하지 않는다.

### 범위 결정 근거

- Go runtime 구현은 수정하지 않는다. Field evidence를 수집하다 실제 code defect가 발견되면 이 plan을 확장하지 말고 review 결과에서 별도 follow-up으로 분리한다.
- Remote `build/dev-runtime/edge.yaml`은 ignored runtime artifact다. refresh block 보정이 필요하면 token/endpoint를 출력하지 말고 sanitized snippet만 review stub에 기록한다.
- Provider private endpoint, token, API key 원문은 tracked docs, roadmap, review output에 기록하지 않는다.
- 정확한 per-request `node_id`는 공개 API가 노출하지 않으므로 dispatch trace가 없으면 aggregate smoke로 판정한다.

### 빌드 등급

- `cloud-G08`: 원격 runner, process lifecycle, multi-host Node reconnect, provider pool runtime, concurrent OpenAI-compatible request evidence가 중심이라 local bounded verification 조건을 만족하지 않는다.

## 구현 체크리스트

- [ ] `REVIEW_TEST-1` dev-runtime 검증 계약을 actual artifact에 맞춘다. 검증: local docs/agent-test command가 `build/dev-runtime/bin/edge` 또는 명시적 `EDGE_BIN` discovery를 사용하고, remote preflight가 binary/config/port 상태를 token 없이 기록한다.
- [ ] `REVIEW_TEST-2` 원격 dev-runtime baseline을 준비하고 Edge restart 후 bootstrap 재실행 없이 3개 Node가 회복되는 evidence를 수집한다. 검증: Control Plane status와 Edge node TCP connection 수가 3개 Node 기준으로 회복된다.
- [ ] `REVIEW_TEST-3` `gx10-vllm=4`, `onexplayer-lemonade=3` capacity를 refresh apply로 반영하고 Edge PID 유지와 `qwen3.6:35b` 동시 4개 요청 성공 evidence를 수집한다. 검증: refresh apply JSON, Edge PID before/after 동일성, `/healthz`, `/v1/models`, 4-line concurrent JSONL이 존재한다.
- [ ] `REVIEW_TEST-4` docs와 agent-test field 기준이 실제 field 결과와 일치하는지 확인하고 필요한 문서/agent-test 기준만 보정한다.
- [ ] 최종 검증 명령을 모두 실행하고 실제 stdout/stderr를 `CODE_REVIEW-cloud-G08.md`에 붙여 넣는다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

## 의존 관계 및 구현 순서

순서는 `REVIEW_TEST-1` command/config 정합화, `REVIEW_TEST-2` reconnect evidence, `REVIEW_TEST-3` refresh/concurrency evidence, `REVIEW_TEST-4` docs consistency 순서다. `REVIEW_TEST-2`와 `REVIEW_TEST-3`은 같은 dev-runtime baseline을 공유하므로 baseline 준비를 중복하지 않는다.

### [REVIEW_TEST-1] Dev-Runtime Verification Contract

문제: prior plan command는 `iop-edge` 또는 `./build/dev-runtime/iop-edge`만 찾았지만 actual remote artifact는 `build/dev-runtime/bin/edge`였다. `docs/edge-local-dev-guide.md:123`과 `agent-test/local/edge-smoke.md:116`부터 이어지는 dev-runtime 기준도 actual binary/config 상태를 명확히 안내하지 않는다.

해결 방법: field guide와 agent-test 기준에서 dev-runtime 명령을 `EDGE_BIN=build/dev-runtime/bin/edge` 또는 그 경로를 포함한 discovery로 고친다. Remote preflight는 binary path, refresh block, target capacity, process/port 상태만 기록하고 token/endpoint 원문은 출력하지 않는다.

수정 파일 및 체크리스트:

- [ ] `docs/edge-local-dev-guide.md`의 dev-runtime refresh 명령을 actual remote artifact 기준으로 수정한다.
- [ ] `agent-test/local/edge-smoke.md`의 dev-runtime 기준에 actual binary path 또는 discovery 규칙을 반영한다.
- [ ] `agent-test/local/rules.md`는 field 기준이 바뀐 경우에만 수정한다.
- [ ] `apps/edge/README.md`는 일반 package-local `iop-edge` 안내와 실제 field evidence가 모순될 때만 수정한다.

테스트 작성: 새 automated test는 작성하지 않는다. 이 항목은 docs/agent-test 계약 보정이다.

중간 검증:

```bash
rg --sort path -n "\./iop-edge --config build/dev-runtime/edge.yaml|build/dev-runtime/iop-edge|build/bin/iop-edge" docs/edge-local-dev-guide.md agent-test/local/edge-smoke.md
```

Expected: no stale dev-runtime binary command remains. If `rg` exits 1 with no matches, record that as pass.

```bash
ssh toki@toki-labs.com 'set -euo pipefail
cd /Users/toki/agent-work/iop-dev
printf "edge_bin="; test -x build/dev-runtime/bin/edge && echo build/dev-runtime/bin/edge
printf "control_plane_bin="; test -x build/dev-runtime/bin/control-plane && echo build/dev-runtime/bin/control-plane
printf "node_bin="; test -x build/dev-runtime/bin/iop-node && echo build/dev-runtime/bin/iop-node
printf "refresh_block="; grep -n "^refresh:" build/dev-runtime/edge.yaml || echo absent
printf "capacity_lines=\n"; grep -nE "id: \"(gx10-vllm|onexplayer-lemonade)\"|capacity:" build/dev-runtime/edge.yaml | sed -E "s/(token: ).*/\1<masked>/"
for port in 18001 18083 18084 19093; do
  printf "port_%s=" "$port"
  (lsof -nP -iTCP:$port -sTCP:LISTEN 2>/dev/null | awk "NR>1{print \$1\":\"\$2; found=1} END{if(!found) print \"CLOSED\"}") || echo CLOSED
done
'
```

Expected: command exits 0 and prints binary/config/port state without token or provider endpoint values.

### [REVIEW_TEST-2] Field Reconnect Evidence

문제: `field-reconnect` remains incomplete. SDD S16 requires remote dev status and TCP evidence showing 3 Nodes recover after Edge restart without rerunning bootstrap.

해결 방법: Prepare the remote dev-runtime baseline with existing ignored runtime artifacts. If `refresh:` is absent, add only the static loopback refresh block to `build/dev-runtime/edge.yaml` and record a sanitized snippet. Start missing CP/Edge/Node processes from `build/dev-runtime/bin/*` using existing `build/dev-runtime/*.yaml` configs. Then restart only Edge and collect before/after status plus TCP connection evidence. Do not rerun Node bootstrap commands.

수정 파일 및 체크리스트:

- [ ] Remote `build/dev-runtime/edge.yaml` has `refresh.enabled=true` and `listen=127.0.0.1:19093`; record sanitized snippet only.
- [ ] Remote CP, Edge, and `node-codex`, `node-gx10-vllm`, `node-onexplayer-lemonade` processes are running from `build/dev-runtime/bin/*`.
- [ ] `CODE_REVIEW-cloud-G08.md` records before status, before TCP count, Edge PID before/after, after status, after TCP count.
- [ ] `CODE_REVIEW-cloud-G08.md` explicitly records that Node bootstrap commands were not rerun.

테스트 작성: 새 automated test는 작성하지 않는다. This is SDD S16 field evidence.

중간 검증:

```bash
ssh toki@toki-labs.com 'set -euo pipefail
cd /Users/toki/agent-work/iop-dev
mkdir -p /tmp/iop-field-evidence build/dev-runtime/logs
CP_BIN=build/dev-runtime/bin/control-plane
EDGE_BIN=build/dev-runtime/bin/edge
NODE_BIN=build/dev-runtime/bin/iop-node
CP_CONFIG=build/dev-runtime/control-plane.yaml
EDGE_CONFIG=build/dev-runtime/edge.yaml
test -x "$CP_BIN"
test -x "$EDGE_BIN"
test -x "$NODE_BIN"
python3 - <<'"'"'PY'"'"'
from pathlib import Path
p = Path("build/dev-runtime/edge.yaml")
s = p.read_text()
if "\nrefresh:" not in "\n" + s:
    marker = "\nopenai:"
    insert = "\nrefresh:\n  enabled: true\n  listen: \"127.0.0.1:19093\"\n"
    if marker not in s:
        raise SystemExit("openai marker not found in edge.yaml")
    p.write_text(s.replace(marker, insert + marker, 1))
PY
"$EDGE_BIN" --config "$EDGE_CONFIG" config check | tee /tmp/iop-field-evidence/dev-runtime-config-check.txt
if ! lsof -nP -iTCP:18001 -sTCP:LISTEN >/dev/null 2>&1; then
  nohup "$CP_BIN" --config "$CP_CONFIG" serve > build/dev-runtime/logs/control-plane.log 2>&1 &
  echo $! > build/dev-runtime/control-plane.pid
fi
if ! lsof -nP -iTCP:18083 -sTCP:LISTEN >/dev/null 2>&1; then
  nohup "$EDGE_BIN" --config "$EDGE_CONFIG" serve > build/dev-runtime/logs/edge.log 2>&1 &
  echo $! > build/dev-runtime/edge.pid
fi
for name in node-codex node-gx10-vllm node-onexplayer-lemonade; do
  cfg="build/dev-runtime/${name}.yaml"
  test -f "$cfg"
  if ! pgrep -f "iop-node.*${cfg}" >/dev/null 2>&1; then
    nohup "$NODE_BIN" --config "$cfg" serve > "build/dev-runtime/logs/${name}.log" 2>&1 &
    echo $! > "build/dev-runtime/${name}.pid"
  fi
done
for i in $(seq 1 120); do
  curl -fsS http://127.0.0.1:18001/edges/edge-toki-labs/status > /tmp/iop-field-evidence/reconnect-before-status.json && break || true
  sleep 1
done
grep -E "mac-codex-node|gx10-vllm-node|onexplayer-lemonade-node" /tmp/iop-field-evidence/reconnect-before-status.json
(lsof -nP -iTCP:18084 -sTCP:ESTABLISHED 2>/dev/null || ss -tn state established "( sport = :18084 )" 2>/dev/null || true) | tee /tmp/iop-field-evidence/reconnect-before-tcp.txt
BEFORE_PID="$(pgrep -f "build/dev-runtime/bin/edge.*serve|edge.*build/dev-runtime/edge.yaml" | head -n 1)"
test -n "$BEFORE_PID"
kill "$BEFORE_PID"
for i in $(seq 1 20); do if ! kill -0 "$BEFORE_PID" 2>/dev/null; then break; fi; sleep 1; done
nohup "$EDGE_BIN" --config "$EDGE_CONFIG" serve > build/dev-runtime/logs/edge.log 2>&1 &
AFTER_PID="$!"
echo "$AFTER_PID" > build/dev-runtime/edge.pid
printf "before_pid=%s after_pid=%s bootstrap_rerun=none\n" "$BEFORE_PID" "$AFTER_PID" | tee /tmp/iop-field-evidence/reconnect-pids.txt
for i in $(seq 1 120); do
  curl -fsS http://127.0.0.1:18001/edges/edge-toki-labs/status > /tmp/iop-field-evidence/reconnect-after-status.json && grep -E "mac-codex-node|gx10-vllm-node|onexplayer-lemonade-node" /tmp/iop-field-evidence/reconnect-after-status.json && break || true
  sleep 1
done
(lsof -nP -iTCP:18084 -sTCP:ESTABLISHED 2>/dev/null || ss -tn state established "( sport = :18084 )" 2>/dev/null || true) | tee /tmp/iop-field-evidence/reconnect-after-tcp.txt
'
```

Expected: command exits 0, the before/after status contains the three node ids, `reconnect-after-tcp.txt` shows 3 established Edge-Node connections or an equivalent connected count, and `reconnect-pids.txt` says `bootstrap_rerun=none`.

### [REVIEW_TEST-3] Field Refresh And Concurrent Requests

문제: `field-refresh` remains incomplete. SDD S17 requires refresh result evidence and 4 concurrent `qwen3.6:35b` OpenAI-compatible requests without Edge restart.

해결 방법: Use the same running dev-runtime baseline. Run `config refresh --mode dry-run` and `--mode apply` against the running refresh listener. Confirm Edge PID stays the same. Then call `/healthz`, `/v1/models`, and 4 concurrent `/v1/chat/completions`; save raw JSONL evidence.

수정 파일 및 체크리스트:

- [ ] `CODE_REVIEW-cloud-G08.md` includes refresh dry-run JSON and apply JSON.
- [ ] `CODE_REVIEW-cloud-G08.md` includes Edge PID before/after and confirms they are identical.
- [ ] `CODE_REVIEW-cloud-G08.md` includes health/models output.
- [ ] `CODE_REVIEW-cloud-G08.md` includes `refresh-concurrent-4.jsonl` output or saved path plus `wc -l` result of 4.
- [ ] If dispatch trace is unavailable, record aggregate smoke basis and the public API limitation.

테스트 작성: 새 automated test는 작성하지 않는다. This is SDD S17 remote field evidence.

중간 검증:

```bash
ssh toki@toki-labs.com 'set -euo pipefail
cd /Users/toki/agent-work/iop-dev
mkdir -p /tmp/iop-field-evidence
EDGE_BIN=build/dev-runtime/bin/edge
EDGE_CONFIG=build/dev-runtime/edge.yaml
REFRESH_ADDR="$(python3 - <<'"'"'PY'"'"'
from pathlib import Path
import re
s = Path("build/dev-runtime/edge.yaml").read_text()
m = re.search(r"(?ms)^refresh:\n(?:^[ \t]+.*\n)*?^[ \t]+listen:[ \t]*\"?([^\"\n]+)\"?", s)
print(m.group(1).strip() if m else "127.0.0.1:19093")
PY
)"
EDGE_PID_BEFORE="$(pgrep -f "build/dev-runtime/bin/edge.*serve|edge.*build/dev-runtime/edge.yaml" | head -n 1)"
test -n "$EDGE_PID_BEFORE"
"$EDGE_BIN" --config "$EDGE_CONFIG" config refresh --mode dry-run --addr "$REFRESH_ADDR" | tee /tmp/iop-field-evidence/refresh-dry-run.json
"$EDGE_BIN" --config "$EDGE_CONFIG" config refresh --mode apply --addr "$REFRESH_ADDR" | tee /tmp/iop-field-evidence/refresh-apply.json
EDGE_PID_AFTER="$(pgrep -f "build/dev-runtime/bin/edge.*serve|edge.*build/dev-runtime/edge.yaml" | head -n 1)"
printf "edge_pid_before=%s edge_pid_after=%s\n" "$EDGE_PID_BEFORE" "$EDGE_PID_AFTER" | tee /tmp/iop-field-evidence/refresh-pid.txt
test "$EDGE_PID_BEFORE" = "$EDGE_PID_AFTER"
curl -fsS http://toki-labs.com:18083/healthz | tee /tmp/iop-field-evidence/refresh-healthz.txt
curl -fsS http://toki-labs.com:18083/v1/models | tee /tmp/iop-field-evidence/refresh-models.json
python3 - <<'"'"'PY'"'"' | tee /tmp/iop-field-evidence/refresh-concurrent-4.jsonl
import concurrent.futures, json, urllib.request
url = "http://toki-labs.com:18083/v1/chat/completions"
payload = {
  "model": "qwen3.6:35b",
  "messages": [{"role": "user", "content": "Reply with exactly IOP_FIELD_REFRESH_OK."}],
  "max_tokens": 32,
  "temperature": 0
}
def one(i):
    data = json.dumps(payload).encode()
    req = urllib.request.Request(url, data=data, headers={"Content-Type": "application/json"})
    with urllib.request.urlopen(req, timeout=300) as resp:
        body = json.loads(resp.read().decode())
    return {"index": i, "status": "ok", "id": body.get("id"), "model": body.get("model"), "usage": body.get("usage"), "content": body.get("choices", [{}])[0].get("message", {}).get("content", "")}
with concurrent.futures.ThreadPoolExecutor(max_workers=4) as ex:
    for item in ex.map(one, range(4)):
        print(json.dumps(item, ensure_ascii=False))
PY
test "$(wc -l < /tmp/iop-field-evidence/refresh-concurrent-4.jsonl)" = "4"
'
```

Expected: command exits 0, dry-run/apply JSON is saved, Edge PID before/after is identical, health/models succeeds, and `refresh-concurrent-4.jsonl` has 4 successful JSON lines.

### [REVIEW_TEST-4] Docs And Field Rule Consistency

문제: SDD S18 requires docs and field smoke criteria to reflect actual reconnect/config refresh behavior. Prior stale wording checks passed, but actual dev-runtime command path and refresh config readiness were not reflected.

해결 방법: Compare the final field evidence against `apps/edge/README.md`, `docs/edge-local-dev-guide.md`, `agent-test/local/rules.md`, and `agent-test/local/edge-smoke.md`. Keep general product docs on `iop-edge` package UX, but make dev-runtime-specific commands use actual artifact paths or robust discovery. Do not document token or private endpoint values.

수정 파일 및 체크리스트:

- [ ] `apps/edge/README.md` remains aligned with package-local `iop-edge config refresh` and reconnect policy.
- [ ] `docs/edge-local-dev-guide.md` uses actual dev-runtime binary/config commands where it references `build/dev-runtime/edge.yaml`.
- [ ] `agent-test/local/edge-smoke.md` records the actual dev-runtime binary/config baseline and field evidence criteria.
- [ ] `agent-test/local/rules.md` remains aligned with field/bootstrap criteria if any baseline changed.

테스트 작성: 새 automated test는 작성하지 않는다. Use deterministic text checks plus field evidence.

중간 검증:

```bash
git diff -- apps/edge/README.md docs/edge-local-dev-guide.md
rg --sort path -n "build/dev-runtime/bin/edge|EDGE_BIN|config refresh|Node reconnect|gx10-vllm|onexplayer-lemonade" docs/edge-local-dev-guide.md agent-test/local/edge-smoke.md agent-test/local/rules.md
! rg --sort path -n "hot reload되지 않는다|자동 재등록 루프를 보장하지 않으므로|Edge process restart 후 새 capacity|\./iop-edge --config build/dev-runtime/edge.yaml|build/dev-runtime/iop-edge|build/bin/iop-edge" apps/edge/README.md docs/edge-local-dev-guide.md agent-test/local/rules.md agent-test/local/edge-smoke.md
```

Expected: tracked docs diff is limited to reconnect/refresh field command corrections; positive `rg` shows the new actual dev-runtime baseline; negative `rg` has no matches.

## 수정 파일 요약

| 파일 | 항목 |
|------|------|
| `docs/edge-local-dev-guide.md` | REVIEW_TEST-1, REVIEW_TEST-4 |
| `agent-test/local/edge-smoke.md` | REVIEW_TEST-1, REVIEW_TEST-4 |
| `agent-test/local/rules.md` | REVIEW_TEST-4 if needed |
| `apps/edge/README.md` | REVIEW_TEST-4 if field evidence contradicts current text |
| `agent-task/m-runtime-reconnect-config-refresh/07+01,03,04,05,06_field_docs_smoke/CODE_REVIEW-cloud-G08.md` | REVIEW_TEST-1, REVIEW_TEST-2, REVIEW_TEST-3, REVIEW_TEST-4 |

## 최종 검증

```bash
git diff --check
```

Expected: no output.

```bash
! rg --sort path -n "hot reload되지 않는다|자동 재등록 루프를 보장하지 않으므로|Edge process restart 후 새 capacity|\./iop-edge --config build/dev-runtime/edge.yaml|build/dev-runtime/iop-edge|build/bin/iop-edge" apps/edge/README.md docs/edge-local-dev-guide.md agent-test/local/rules.md agent-test/local/edge-smoke.md
```

Expected: no matches.

```bash
ssh toki@toki-labs.com 'test -s /tmp/iop-field-evidence/reconnect-after-status.json && test -s /tmp/iop-field-evidence/reconnect-after-tcp.txt && test -s /tmp/iop-field-evidence/reconnect-pids.txt && test -s /tmp/iop-field-evidence/refresh-apply.json && test -s /tmp/iop-field-evidence/refresh-pid.txt && test -s /tmp/iop-field-evidence/refresh-concurrent-4.jsonl && test "$(wc -l < /tmp/iop-field-evidence/refresh-concurrent-4.jsonl)" = "4"'
```

Expected: command exits 0.

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