<!-- task=m-bridge-boundary-hardening/02_terminal_core_boundary plan=2 tag=REVIEW_REVIEW_REFACTOR -->

# Plan - REVIEW_REVIEW_REFACTOR

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

이 작업은 두 번째 리뷰에서 발견된 full-cycle 검증 신뢰 문제를 닫는 follow-up이다. 구현 후 active 파일을 유지하고, 반드시 `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 실제 검증 내용과 stdout/stderr로 채운 뒤 리뷰 준비 상태로 멈춘다. 구현 중 사용자 결정, 사용자 소유 외부 환경, 또는 계획 범위 충돌 없이는 진행할 수 없으면 review stub의 `사용자 리뷰 요청` 섹션에 근거를 남기고 중단한다. 구현 중 사용자에게 직접 질문하거나 `USER_REVIEW.md`, `complete.log`, archive log를 만들지 않는다. 증거 공백은 후속 에이전트가 명령 재실행이나 산출물 수집으로 해소할 수 있으면 사용자 리뷰 요청이 아니다.

## 배경

두 번째 리뷰에서 Go 테스트는 통과했지만 full-cycle 증거가 여전히 신뢰할 수 없었다. 특히 두 번째 run의 edge/node 출력에는 partial payload fragment가 있었는데 비교표는 이를 누락하고 `result=same`으로 기록했다. 이 follow-up은 source refactor 범위를 넓히지 않고 deterministic terminal 진단과 정확한 payload 비교를 다시 수행한다.

## 사용자 리뷰 요청 흐름

구현 중 차단은 active review stub의 `사용자 리뷰 요청` 섹션에 기록한다. 직접 사용자 프롬프트는 금지하며, code-review가 요청 타당성을 검증하고 실제 `USER_REVIEW.md` 생성을 소유한다.

## Roadmap Targets

- Milestone: `agent-roadmap/phase/automation-runtime-bridge/milestones/bridge-boundary-hardening.md`
- Task ids:
  - `terminal-core-boundary`: persistent PTY 기반 `terminalSessionCore`를 CLI provider 내부 세부가 아니라 remote terminal transport가 재사용할 수 있는 Node terminal boundary로 분리하거나 명시 interface로 고정한다.
- Completion mode: check-on-pass

## 분석 결과

### 읽은 파일

- `agent-task/m-bridge-boundary-hardening/02_terminal_core_boundary/plan_cloud_G07_1.log`
- `agent-task/m-bridge-boundary-hardening/02_terminal_core_boundary/code_review_cloud_G07_1.log`
- `agent-ops/rules/project/domain/testing/rules.md`
- `agent-test/local/testing-smoke.md`
- `agent-ops/skills/project/e2e-smoke/SKILL.md`
- `scripts/dev/edge.sh`
- `scripts/dev/node.sh`
- `scripts/e2e-smoke.sh`
- `apps/node/internal/adapters/cli/persistent.go`
- `apps/node/internal/terminal/session.go`

### 테스트 환경 규칙

- test_env: `local`.
- 적용 규칙: 사용자 실행 파이프라인에 닿는 adapter execution/session 변경은 Go 테스트와 full-cycle 실제 구동을 함께 검증한다.
- 핵심 판정 기준: node 로컬 `[node-message]` payload line 목록과 edge `[node0-msg]` payload line 목록이 run별로 내용/순서까지 동일해야 한다. partial fragment를 임의로 버리면 안 된다.
- 보조 `./scripts/e2e-smoke.sh`는 auxiliary evidence로만 기록한다.

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

- Go package tests는 reviewer rerun 기준 통과했다.
- 남은 공백: full-cycle 진단 출력의 두 번째 run payload comparison이 partial fragment를 누락해 신뢰할 수 없다. auxiliary smoke 출력도 run id가 내부적으로 섞여 있어 다시 캡처해야 한다.

### 심볼 참조

- 새 symbol rename은 없다. 기존 stale reference 검색은 이전 리뷰에서 완료됐다.

### 분할 판단

- 기존 split subtask `02_terminal_core_boundary`의 follow-up이며 새 subtask를 만들지 않는다.
- sibling `01_edge_run_surface`, `03_adapter_config_typed`와 독립이다.

### 범위 결정 근거

- source 변경은 기본적으로 하지 않는다.
- full-cycle 재실행 결과가 실제 relay/session regression을 보여줄 때만 최소 코드 수정과 추가 검증을 포함한다.
- 임시 config는 기본 `configs/*.yaml`을 수정하지 말고 `/tmp` 아래에 만들거나, repo 안에 만들었다면 완료 전 삭제하고 review stub에 config 내용을 붙인다.

### 빌드 등급

- `cloud-G07`: terminal/CLI process control 검증 신뢰 회수이며, stdout/stderr와 payload comparison을 엄밀하게 판단해야 한다.

## 구현 체크리스트

- [ ] deterministic terminal profile을 사용하는 repo 내부 edge-node full-cycle 진단을 수행하고, terminal command는 입력 echo를 줄이기 위해 `stty -echo`를 적용한다.
- [ ] 각 foreground run마다 edge `[node0-msg]` payload line과 node `[node-message]` payload line을 partial fragment 포함 그대로 추출해 비교하고, 누락 없이 `same` 또는 `different`를 기록한다.
- [ ] `./scripts/e2e-smoke.sh`를 다시 실행하고, run id가 내부적으로 일관된 실제 stdout/stderr 또는 저장 경로를 기록한다. 이 결과는 auxiliary only로 분리한다.
- [ ] Go 검증 명령 `go test -count=1 ./apps/node/internal/terminal ./apps/node/internal/adapters/cli`와 `go test -count=1 ./apps/node/internal/adapters/cli ./apps/node/internal/...`를 재실행하고 실제 stdout/stderr를 검증 결과에 기록한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

### [REVIEW_REVIEW_REFACTOR-1] Re-capture Deterministic Full-Cycle Payload Evidence

문제: `code_review_cloud_G07_1.log`의 full-cycle output에는 두 번째 run의 partial payload fragment가 포함되어 있으나 comparison table은 해당 fragment를 누락하고 `same`으로 기록했다. 또한 auxiliary smoke output은 run id가 내부적으로 섞여 있어 stdout/stderr 증거로 신뢰하기 어렵다.

해결 방법: `/tmp` 아래 임시 edge/node config와 fake CLI를 만들고, fake CLI는 terminal profile에서 `stty -echo` 후 입력 line을 읽어 deterministic payload만 출력한다. `scripts/dev/edge.sh`와 `scripts/dev/node.sh`를 별도 프로세스로 실행하고 edge console에 `/nodes`, foreground message 2회, `/capabilities`, `/transport`, `/sessions`, `/terminate-session`, `/exit`를 입력한다. 비교는 raw output에서 모든 `[node-message]`와 `[node0-msg]` 줄을 run별로 추출해 수행한다. fragment가 존재하면 comparison에 그대로 포함하고 `different`로 남긴다.

수정 파일 및 체크리스트:

- [ ] `agent-task/m-bridge-boundary-hardening/02_terminal_core_boundary/CODE_REVIEW-cloud-G07.md`: deterministic full-cycle stdout/stderr, exact payload comparison, auxiliary smoke output, Go test output을 기록한다.
- [ ] Source file 변경은 기본적으로 하지 않는다. full-cycle mismatch가 실제 regression이면 최소 코드 수정과 해당 수정 검증을 추가 기록한다.

테스트 작성: 새 테스트 파일은 작성하지 않는다. 이 follow-up은 검증 증거 회수와 필요 시 최소 regression fix다.

중간 검증:

```bash
go test -count=1 ./apps/node/internal/terminal ./apps/node/internal/adapters/cli
```

```bash
./scripts/e2e-smoke.sh
```

## 수정 파일 요약

| 파일 | 항목 |
|------|------|
| `agent-task/m-bridge-boundary-hardening/02_terminal_core_boundary/CODE_REVIEW-cloud-G07.md` | REVIEW_REVIEW_REFACTOR-1 |

## 최종 검증

```bash
go test -count=1 ./apps/node/internal/adapters/cli ./apps/node/internal/...
```

Repo 내부 edge-node full-cycle 진단:

```bash
IOP_EDGE_CONFIG=/tmp/<tmp-edge-yaml> ./scripts/dev/edge.sh
IOP_NODE_CONFIG=/tmp/<tmp-node-yaml> ./scripts/dev/node.sh
```

Edge console에서 순서대로 `/nodes`, foreground 메시지 2회, `/capabilities`, `/transport`, `/sessions`, `/terminate-session`, `/exit`를 입력한다. 기대 결과는 node register, 각 foreground run의 sent/start/message/complete 순서, node-local payload와 edge-rendered payload의 run별 동일성, command 응답 표시, terminate-session 성공이다. partial fragment가 있으면 비교표에 포함하고 PASS로 주장하지 않는다.

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