<!-- task=m-codex-app-server-streaming-migration/04+03_stream_smoke plan=0 tag=TEST -->
# Codex App Server Stream Smoke Plan

## 이 파일을 읽는 구현 에이전트에게
이 PLAN을 끝까지 읽은 뒤 구현한다. 먼저 선행 작업 `03+02_default_profile/complete.log`가 있는지 확인한다. 없으면 구현하지 말고 선행 작업을 완료한다. 구현 완료 전 `CODE_REVIEW-cloud-G07.md`의 구현 에이전트 소유 섹션을 실제 변경 내용과 검증 출력으로 채운다.

## 배경
마일스톤의 마지막 검증은 기본 `codex` target이 app-server streaming 경로로 동작하고, 두 번의 프롬프트에서 같은 thread/session을 재사용하며, `codex-exec` fallback도 보존되는지 확인하는 것이다.

## 사용자 리뷰 요청 흐름
외부 Codex 계정, 네트워크, quota, 또는 로그인 상태 때문에 실제 app-server smoke가 실행 불가할 때만 사용자 리뷰 요청을 남긴다. 그 전에는 fake adapter 단위 테스트와 local script 검증을 모두 수행한다.

## Roadmap Targets

- Milestone: `agent-roadmap/phase/automation-runtime-bridge/milestones/codex-app-server-streaming-migration.md`
- Task ids:
  - `stream-smoke`: `./scripts/dev/edge.sh`와 `./scripts/dev/node.sh` 시작 후 `codex` target으로 2-message 왕복에서 델타 스트림이 관찰된다. 검증: 두 메시지가 같은 logical session에서 완료되고, 적어도 한 turn에서 app-server delta event가 IOP delta로 relay된다.
- Completion mode: check-on-pass

## 의존 관계 및 구현 순서
- 현재 subtask: `04+03_stream_smoke`
- 선행 index `03`: `agent-task/m-codex-app-server-streaming-migration/03+02_default_profile/complete.log`가 현재 없음. 구현 전 선행 작업 완료가 필요하다.

## 분석 결과
### 읽은 파일
- Smoke: `scripts/e2e-smoke.sh`, `scripts/dev/edge.sh`, `scripts/dev/node.sh`, `Makefile`
- Runtime/console: `apps/node/internal/node/node.go`, `apps/edge/internal/opsconsole/events.go`, `apps/edge/internal/opsconsole/events_test.go`
- Adapter: `apps/node/internal/adapters/cli/cli.go`, `apps/node/internal/adapters/cli/opencode_sse.go`, `apps/node/internal/adapters/cli/emitters.go`
- 설정: `configs/edge.yaml`, `configs/edge-compose.yaml.tmpl`
- 선행 plan: `agent-task/m-codex-app-server-streaming-migration/03+02_default_profile/PLAN-local-G05.md`

### 테스트 환경 규칙
- 환경 미지정은 local로 본다.
- 선행 완료 확인: `test -f agent-task/m-codex-app-server-streaming-migration/03+02_default_profile/complete.log`
- 기본 검증 후보: `go test ./apps/node/... ./apps/edge/... -count=1`, `./scripts/e2e-smoke.sh`
- 실제 external CLI 검증은 `scripts/dev/edge.sh`와 `scripts/dev/node.sh`를 통한 full-cycle smoke로 수행한다.

### 테스트 커버리지 공백
- 현재 smoke는 기본 profile이 app-server streaming source인지 명시적으로 확인하지 않는다.
- Edge console 출력은 delta text 중심이라 metadata가 사용자 화면에 드러나지 않을 수 있다.
- 두 번째 프롬프트가 같은 Codex thread를 재사용했는지 확인하는 assertion이 없다.

### 심볼 참조
- 기존 smoke 명령명 변경 없음.
- 필요 시 runtime event metadata 또는 node log 기반 assertion을 추가한다.
- 호출 지점: `/capabilities`, `/transport`, `/sessions`, `/terminate-session`, 두 차례 prompt 실행.

### 분할 판단
분할 정책을 평가했고 공유 task group은 `agent-task/m-codex-app-server-streaming-migration/`이다. sibling subtask는 `01_appserver_rpc_client`(선행 없음), `02+01_session_events`(`01` 의존), `03+02_default_profile`(`02` 의존), `04+03_stream_smoke`(`03` 의존)이다. 현재 작업의 predecessor index `03`은 active `complete.log`가 없어서 미충족이다.

### 범위 결정 근거
smoke는 사용자 관측 경로를 검증하는 작업이다. adapter 내부 구현 변경은 smoke assertion을 가능하게 하는 최소 범위로 제한한다.

### 빌드 등급
`cloud-G07`: 실제 Codex CLI app-server와 account 상태가 필요하고, Edge/Node 프로세스 간 streaming relay까지 검증해야 한다.

## 구현 체크리스트
- [ ] 선행 `03+02_default_profile/complete.log`를 확인한다.
- [ ] e2e smoke가 기본 `codex` target을 app-server 경로로 식별할 수 있게 한다.
- [ ] 첫 번째 prompt의 streaming delta와 completed event를 확인한다.
- [ ] 두 번째 prompt가 같은 IOP session/Codex thread를 재사용하는지 확인한다.
- [ ] `/sessions`와 `/terminate-session`이 app-server session을 보여주고 정리하는지 확인한다.
- [ ] `codex-exec` fallback profile이 capabilities에 남아 있고 필요 시 별도 smoke로 실행 가능한지 확인한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

### [TEST-1] app-server source 식별 assertion 추가
문제: streaming delta가 보이더라도 `codex exec --json` 경로인지 app-server 경로인지 구분하지 못하면 마일스톤 목적을 검증할 수 없다.

해결 방법: app-server RuntimeEvent metadata, node log, 또는 session snapshot 중 안정적인 지점을 골라 `source=codex-app-server`와 `codex_thread_id`를 검증한다. 화면 출력에 metadata를 억지로 노출하지 않고, 테스트 전용 assertion을 우선한다.

수정 파일 및 체크리스트:
- [ ] `scripts/e2e-smoke.sh`
- [ ] 필요 시 `apps/node/internal/adapters/cli/codex_app_server_internal_test.go`

테스트 작성:
- [ ] fake app-server smoke에서 source metadata가 남는지 검증
- [ ] e2e script에서 기본 target이 `codex`인지 검증

중간 검증:
```bash
test -f agent-task/m-codex-app-server-streaming-migration/03+02_default_profile/complete.log
go test ./apps/node/internal/adapters/cli -run 'TestCodexAppServer.*Metadata|TestCodexAppServer.*ThreadReuse' -count=1
```

### [TEST-2] 두 차례 prompt full-cycle smoke
문제: 단일 prompt 성공만으로는 app-server thread 재사용과 session 유지가 검증되지 않는다.

해결 방법: `scripts/e2e-smoke.sh` 또는 dev script 절차에 두 번의 prompt를 포함하고, 두 번째 prompt 전에 `/sessions`로 session id/thread id를 확인한다. 완료 후 `/terminate-session`으로 정리한다.

수정 파일 및 체크리스트:
- [ ] `scripts/e2e-smoke.sh`
- [ ] 필요 시 `apps/edge/internal/opsconsole/events_test.go`

테스트 작성:
- [ ] 두 번째 prompt 전후 session id가 유지되는지 검증
- [ ] terminate 후 session list에서 제거되는지 검증

중간 검증:
```bash
go test ./apps/node/... ./apps/edge/... -count=1
```

### [TEST-3] 실제 CLI smoke 절차 기록
문제: app-server는 실제 Codex CLI/account 상태와 결합되어 있어 단위 테스트만으로 마일스톤 완료 근거가 부족하다.

해결 방법: local/cloud runner에서 Edge와 Node를 띄우고 `codex` target에 두 번 prompt를 보내 streaming delta와 completed event를 기록한다. 같은 환경에서 `codex-exec` fallback이 capabilities에 남아 있는지도 확인한다.

수정 파일 및 체크리스트:
- [ ] `CODE_REVIEW-cloud-G07.md` 검증 출력 섹션
- [ ] 필요 시 `scripts/e2e-smoke.sh`

테스트 작성:
- [ ] 자동화 가능한 부분은 `scripts/e2e-smoke.sh`에 반영
- [ ] 계정 상태 때문에 자동화 불가한 출력은 사용자 리뷰 요청이 아니라 실행 환경 리스크로 기록

중간 검증:
```bash
./scripts/dev/edge.sh
./scripts/dev/node.sh
IOP_E2E_PROFILE=codex ./scripts/e2e-smoke.sh
```

## 수정 파일 요약
| 파일 | 항목 |
| --- | --- |
| `scripts/e2e-smoke.sh` | TEST-1, TEST-2, TEST-3 |
| `apps/node/internal/adapters/cli/codex_app_server_internal_test.go` | TEST-1, 필요 시 |
| `apps/edge/internal/opsconsole/events_test.go` | TEST-2, 필요 시 |
| `CODE_REVIEW-cloud-G07.md` | TEST-3 |

## 최종 검증
```bash
test -f agent-task/m-codex-app-server-streaming-migration/03+02_default_profile/complete.log
go test ./apps/node/... ./apps/edge/... -count=1
IOP_E2E_PROFILE=codex ./scripts/e2e-smoke.sh
```

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