<!-- task=m-agent-readable-repository-refactor/15+14_runtime_full_cycle plan=0 tag=TEST -->

# Runtime Full-Cycle Regression Plan

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

이 Plan은 실제 프로세스와 외부 CLI를 포함하는 최종 regression evidence 단계다. 선행 `14_repository_regression`의 `complete.log`가 정확히 하나 확인된 뒤에만 시작한다. 모든 검증을 실행하고 실제 출력 또는 `/tmp` 로그 경로를 `CODE_REVIEW-cloud-G08.md`의 구현 에이전트 소유 섹션에 기록한 뒤 active 파일을 그대로 두고 review 준비 완료를 보고한다. 최종 판정, 로그 rename, `complete.log`, archive 이동은 code-review 스킬 전용이다.

선택된 Milestone의 `구현 잠금 > 결정 필요`가 실구현을 차단할 때만 review stub의 `사용자 리뷰 요청`에 연결 근거를 기록하고 중단한다. 사용자에게 직접 질문하거나 선택지를 제시하거나 `request_user_input`을 호출하거나 `USER_REVIEW.md`·`complete.log`를 만들지 않는다. 외부 CLI 설치·로그인·provider·endpoint blocker와 evidence 공백은 사용자 리뷰 요청이 아니며 profile별 blocker로 기록한다.

## 배경

저장소 리팩터링은 Edge/Node transport, adapter, OpenAI 입력 표면, Control Plane wire와 Flutter 경로를 넓게 분해했다. 저장소 내부 회귀만으로는 실제 process startup/register, message relay ordering, session/command lifecycle과 외부 CLI 통합을 증명할 수 없으므로 별도 terminal 중심 검증이 필요하다.

## 사용자 리뷰 요청 흐름

구현 중 직접 사용자 입력을 요청하지 않는다. 선택된 Milestone 잠금 결정만 `agent-ops/skills/common/_templates/implementation-user-review-request-section.md` 형식으로 active review stub에 기록하고, 실제 `USER_REVIEW.md` 작성 여부는 code-review가 판정한다. 외부 실행 환경 blocker는 `검증 결과`와 `계획 대비 변경 사항`에 남긴다.

## Roadmap Targets

- Milestone: `agent-roadmap/phase/automation-runtime-bridge/milestones/agent-readable-repository-refactor.md`
- Milestone link: [Milestone 문서](../../../agent-roadmap/phase/automation-runtime-bridge/milestones/agent-readable-repository-refactor.md)
- Task ids:
  - `regression`: 전체 Go/Flutter 회귀와 관련 E2E/full-cycle 검증
- Completion mode: check-on-pass

## 분석 결과

### 읽은 파일

- `agent-roadmap/current.md`
- `agent-roadmap/priority-queue.md`
- `agent-roadmap/phase/automation-runtime-bridge/PHASE.md`
- `agent-roadmap/phase/automation-runtime-bridge/milestones/agent-readable-repository-refactor.md`
- `agent-ops/rules/project/domain/testing/rules.md`
- `agent-ops/rules/project/domain/node/rules.md`
- `agent-ops/skills/project/e2e-smoke/SKILL.md`
- `agent-test/local/rules.md`
- `agent-test/local/testing-smoke.md`
- `agent-test/local/edge-smoke.md`
- `agent-test/local/node-smoke.md`
- `agent-test/local/control-plane-smoke.md`
- `agent-test/local/client-smoke.md`
- `agent-test/local/platform-common-smoke.md`
- `Makefile`
- `scripts/dev/edge.sh`
- `scripts/dev/node.sh`
- `scripts/e2e-smoke.sh`
- `scripts/e2e-openai-ollama.sh`
- `scripts/e2e-control-plane-edge-wire.sh`
- `configs/edge.yaml`
- `configs/node.yaml`
- `apps/edge/README.md`
- `apps/node/README.md`

### SDD 기준

Milestone의 SDD는 불필요하다. 외부 API/proto/config schema나 runtime 책임 경계를 바꾸지 않는 동작 보존형 리팩터링이라는 기존 사유를 따른다.

### 테스트 환경 규칙

- `test_env`: `local`
- `agent-test/local/rules.md`와 testing, edge, node, control-plane, client, platform-common smoke profile을 읽었다.
- runtime 검증은 `agent-ops/skills/project/e2e-smoke/SKILL.md`의 실제 process/message relay 기준을 따른다.
- 현재 runner preflight: repo `/config/workspace/iop`, branch `main`, HEAD `be05139b5be6a7938ac102aaf0664ed08e4cebe3`, dirty worktree, Linux arm64.
- 확인된 도구: Go `1.26.2`, Flutter `3.41.5`, `make`, `bash`, `curl`, `timeout`, `claude`, `agy`, `codex`, `opencode`. `shellcheck`와 `antigravity` 이름의 binary는 없고 Antigravity 실행 command는 문서 기준 `agy`다.
- tracked `configs/edge.yaml`은 provider-first CLI entries `claude-tui`, `codex`, `codex-exec`를 포함하지만 `scripts/e2e-smoke.sh`의 real mode가 읽는 legacy `adapters.cli.profiles`는 주석 예시뿐이다. `antigravity`, `opencode` active profile도 없다.
- 따라서 mock/full-cycle과 OpenAI/Control Plane smoke는 즉시 재현 가능하지만, 실제 외부 CLI 4종은 `/tmp` 임시 config와 각 CLI 로그인/provider 가용성 preflight가 필요하다. tracked config를 임시 profile 값으로 수정하지 않는다.
- 로그와 임시 config는 `/tmp/iop-agent-readable-runtime-full-cycle/`만 사용한다. token/secret, 개인 endpoint, raw prompt/response의 민감 정보는 review artifact에 복사하지 않는다.

### 테스트 환경 프리플라이트

- 선행 evidence: `14_repository_regression`의 active 또는 archive `complete.log`가 정확히 하나 있어야 한다.
- runner/workdir: current local runner, `/config/workspace/iop`
- source sync: 실행 시작 시 branch/HEAD/dirty state를 다시 기록하고 선행 evidence의 HEAD와 비교한다. HEAD가 달라졌으면 repository regression을 재실행하거나 blocker로 기록한다.
- binaries: `command -v go flutter make bash curl timeout claude agy codex opencode`와 각 CLI의 non-interactive version/help command를 먼저 실행한다.
- config: 기본 tracked config를 수정하지 않고 `/tmp`에 mock/real profile별 Edge/Node config를 둔다.
- runtime identity/ports: 임시 node id/token과 loopback 동적 port만 사용한다. 기존 9090/18081/19090 listener를 가정하지 않는다.
- external state: CLI별 로그인, provider, workspace 권한이 필요하다. 실패하면 profile별 실제 명령과 sanitized output을 blocker로 기록한다.

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

- `scripts/e2e-smoke.sh` mock profile은 실제 Edge/Node process를 띄워 register, foreground message 2회, background run, message payload identity/order, capabilities/transport/sessions/terminate를 검증한다.
- `scripts/e2e-openai-ollama.sh`는 fake Ollama와 실제 Edge/Node process로 models/chat/responses/SSE를 검증한다.
- `scripts/e2e-control-plane-edge-wire.sh`는 실제 Control Plane/Edge hello/connect/disconnect를 검증한다.
- 외부 `claude`, `antigravity(agy)`, `codex`, `opencode` 로그인/provider 응답은 unit/mock test가 대체하지 못한다. 네 profile을 실제 호출하지 못하면 profile별 blocker가 남으며 최종 PASS를 주장하지 않는다.
- 이 작업은 동작을 변경하지 않으므로 새 automated test를 추가하지 않는다. smoke 자체의 결함이 발견되면 이 Plan 안에서 고치지 않고 별도 follow-up Plan으로 분리한다.

### 심볼 참조

none. 심볼을 변경하거나 제거하지 않는다.

### 분할 판단

분할 정책을 Plan 파일 선택 전에 적용했다.

- shared task group: `m-agent-readable-repository-refactor`
- predecessor: `14_repository_regression`
- current: `15+14_runtime_full_cycle`

디렉터리 이름의 `+14`가 유일한 runtime dependency다. Plan 작성 시점에는 `14_repository_regression/complete.log`가 아직 없어 미충족이며, 구현은 해당 active 또는 archive `complete.log`가 정확히 하나 생긴 뒤 시작해야 한다. runtime full-cycle 내부는 process lifecycle과 외부 CLI 상태를 함께 보아야 최종 Milestone regression을 판정할 수 있어 더 쪼개지 않는다.

### 범위 결정 근거

- tracked production/test/config/common 파일을 수정하지 않는다.
- `agent-ops/rules/common/**`와 `agent-ops/skills/common/**`는 수정·검증 대상으로 삼지 않는다.
- `/tmp` 외 임시 config/log를 만들지 않는다.
- 실패한 runtime 또는 CLI profile을 고치지 않는다. 최초 실패 evidence와 재현 명령을 남겨 code-review가 follow-up 범위를 정하게 한다.
- Docker, live inference provider, private endpoint를 임의로 추가하지 않는다.

### 빌드 등급

`cloud-G08`. PTY/프로세스 orchestration, stdout/stderr ordering, session lifecycle과 실제 외부 CLI 상태가 중심이며 로컬 unit evidence만으로 판정할 수 없다.

## 구현 체크리스트

- [ ] `14_repository_regression`의 active 또는 archive `complete.log`를 정확히 하나 확인하고 HEAD/evidence를 기록한다.
- [ ] runtime 도구·CLI·로그인/config/port preflight를 실행하고 profile별 가용 상태를 기록한다.
- [ ] mock Edge-Node 실제 process full-cycle을 실행해 register, foreground message 2회, background run, payload identity/order, `/nodes`, `/capabilities`, `/transport`, `/sessions`, `/terminate-session`을 확인한다.
- [ ] `make test-e2e`를 실행해 OpenAI-compatible Ollama와 Control Plane-Edge wire 보조 smoke까지 확인한다.
- [ ] `claude`, `antigravity(agy)`, `codex`, `opencode`를 임시 config로 각각 실제 호출하고 같은 session message 2회, start/message/complete, 지원 command/status를 profile별로 기록한다. 실행 불가 profile은 실제 blocker evidence를 남기고 PASS로 처리하지 않는다.
- [ ] 검증 전후 HEAD/dirty state와 common 파일 무변경을 확인하고 최종 PASS 또는 남은 blocker를 명확히 기록한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

### [TEST-1] Deterministic actual-process full-cycle

#### 문제

보조 package test만으로는 Edge/Node/Control Plane process startup, message relay ordering과 session command lifecycle을 증명할 수 없다.

#### 해결 방법

`/tmp` 전용 cache/config/log를 사용해 mock Edge-Node 실제 process diagnostic을 먼저 실행하고, 이어서 official `make test-e2e` target으로 OpenAI-compatible Ollama와 Control Plane-Edge wire smoke를 실행한다.

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

- [ ] tracked 파일 수정 없음
- [ ] `CODE_REVIEW-cloud-G08.md`: 실제 process 출력, marker, 종료 상태 기록

#### 테스트 작성

새 테스트를 작성하지 않는다. 기존 smoke entrypoint가 요구하는 실제 process lifecycle을 그대로 실행한다.

#### 중간 검증

```bash
mkdir -p /tmp/iop-agent-readable-runtime-full-cycle
command -v go flutter make bash curl timeout
set -o pipefail; GOCACHE=/tmp/iop-agent-readable-runtime-full-cycle/go-cache IOP_E2E_PROFILE=mock ./scripts/e2e-smoke.sh 2>&1 | tee /tmp/iop-agent-readable-runtime-full-cycle/edge-node-mock.log
set -o pipefail; GOCACHE=/tmp/iop-agent-readable-runtime-full-cycle/go-cache make test-e2e 2>&1 | tee /tmp/iop-agent-readable-runtime-full-cycle/make-test-e2e.log
```

기대 결과: actual Edge/Node registration, foreground 2회와 background 1회, node/edge payload identity와 complete ordering, command lifecycle이 PASS하고 OpenAI Ollama 및 Control Plane wire smoke도 종료 코드 0이다.

### [TEST-2] Real external CLI profile matrix

#### 문제

실제 외부 CLI profile은 설치·로그인·provider와 profile config에 의존하며 mock adapter가 그 통합을 증명하지 못한다. 현재 tracked provider-first config와 legacy real-profile smoke loader도 직접 호환되지 않는다.

#### 해결 방법

tracked config를 수정하지 않고 `/tmp`에 문서화된 profile matrix를 구성한다.

| profile | command | mode 기준 |
|---------|---------|-----------|
| `claude` | `claude` | one-shot `-p --dangerously-skip-permissions` |
| `antigravity` | `agy` | `antigravity-print`, conversation resume |
| `codex` | `codex` | `codex-app-server` 또는 문서화된 non-interactive exec |
| `opencode` | `opencode` | `opencode-sse` |

각 profile은 `scripts/dev/edge.sh`와 `scripts/dev/node.sh`를 별도 process로 실행하고, 같은 session message 2회와 command/status 결과를 수집한다. binary/version/help, 로그인/provider, workspace preflight가 실패하면 해당 profile을 실행 성공으로 간주하지 않는다.

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

- [ ] tracked 파일 수정 없음
- [ ] `/tmp/iop-agent-readable-runtime-full-cycle/edge-<profile>.yaml`: sanitized 임시 Edge config
- [ ] `/tmp/iop-agent-readable-runtime-full-cycle/node-<profile>.yaml`: sanitized 임시 Node config
- [ ] `CODE_REVIEW-cloud-G08.md`: profile별 PASS/FAIL/BLOCKED와 실제 명령/로그 기록

#### 테스트 작성

새 테스트를 작성하지 않는다. 실제 CLI 프로세스와 계정/provider 상태를 검증하는 field-like execution evidence다.

#### 중간 검증

```bash
for cmd in claude agy codex opencode; do
  printf '%s=' "$cmd"
  command -v "$cmd"
done
claude --version
agy --help
codex --version
opencode --version
```

기대 결과: 네 command가 모두 확인되고 secret을 출력하지 않는 version/help preflight가 성공한다. 이후 profile별 Edge/Node PTY run에서 같은 session message 2회가 sent/start/non-empty-message/complete 순서로 끝나야 한다.

## 의존 관계 및 구현 순서

1. `14_repository_regression`의 `complete.log`가 active 또는 `agent-task/archive/*/*/m-agent-readable-repository-refactor/14_repository_regression/complete.log`에 정확히 하나 존재해야 한다.
2. TEST-1 actual-process deterministic full-cycle을 실행한다.
3. TEST-2 real CLI matrix를 실행한다.
4. 네 real profile 중 하나라도 미실행/실패/blocker면 이를 숨기지 않고 review evidence에 남기며 Milestone `regression` PASS를 주장하지 않는다.

## 수정 파일 요약

| 파일 | 항목 |
|------|------|
| `CODE_REVIEW-cloud-G08.md` | TEST-1, TEST-2 실제 evidence 기록 |

## 최종 검증

```bash
git rev-parse HEAD
git status --short
git diff --check
git diff --name-only | rg '^agent-ops/(rules|skills)/common/' && exit 1 || true
rg -n --sort path 'Auxiliary smoke test PASSED|OpenAI-compatible Ollama serving test PASSED|Control Plane-Edge wire smoke PASSED' /tmp/iop-agent-readable-runtime-full-cycle/*.log
```

기대 결과: preflight/선행 evidence와 같은 HEAD, whitespace 오류 없음, common 파일 diff 없음, deterministic runtime marker 3종 PASS다. 별도로 real CLI 네 profile 모두 message 2회와 profile별 command/status evidence가 있어야 최종 PASS다.

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