<!-- task=cli_usage_status_command plan=1 tag=REVIEW_API -->

# Code Review Reference - REVIEW_API

## 개요

date=2026-05-04
task=cli_usage_status_command, plan=1, tag=REVIEW_API

## 이 파일을 읽는 리뷰 에이전트에게

각 항목의 구현을 실제 소스 파일과 대조하고, `검증 결과` 섹션의 출력이 코드와 일치하는지 확인하세요.
리뷰 완료 후 반드시 아래 순서로 아카이브하세요.

1. `CODE_REVIEW.md` → `code_review_N.log` (N = 기존 code_review_*.log 수)
2. `PLAN.md` → `plan_M.log` (M = 기존 plan_*.log 수)
3. PASS인 경우 `complete.log` 작성 후 종료. WARN/FAIL인 경우 새 `PLAN.md` + `CODE_REVIEW.md` 스텁 작성.

---

## 구현 항목별 완료 여부

| 항목 | 완료 여부 |
|------|---------|
| [REVIEW_API-1] `configs/edge.yaml` codex profile 복원 | [PASS] |
| [REVIEW_API-2] status command 테스트를 fake checker/factory 기반으로 변경 | [PASS] |
| [REVIEW_API-3] `/status` request timeout 보정값을 edge wait timeout에도 사용 | [PASS] |
| [REVIEW_API-4] Go formatting과 whitespace check 통과 | [PASS] |

## 계획 대비 변경 사항

- `packages/config/integration_test.go`를 임시로 만들어 실제 `configs/edge.yaml` 로딩을 검증한 뒤, 해당 로직을 `packages/config/config_test.go`의 유닛 테스트로 이관하고 임시 파일은 삭제했습니다.

## 주요 설계 결정

- `apps/node/internal/adapters/cli/status/status.go`에서 `NewChecker` factory를 export하여 외부(특히 `cli` adapter 테스트)에서 checker 생성을 검증하거나 fake checker를 주입하기 쉽게 했습니다.
- `CLI` struct에 `StatusChecker` 함수 필드를 추가하여 `HandleCommand` 테스트 시 외부 실행 없이 status logic을 검증할 수 있도록 했습니다.

## 리뷰어를 위한 체크포인트

- `configs/edge.yaml`의 `codex` profile이 실제 `codex` command와 `output_format: codex-json`를 유지하는지 확인한다.
- status tests가 외부 binary 실행 실패 문구에 의존하지 않고 fake checker/factory 또는 순수 factory assertion으로 agent/profile command 선택을 검증하는지 확인한다.
- `/status` edge wait timeout이 `req.GetTimeoutSec()`의 보정값을 기준으로 계산되는지 확인한다.
- `gofmt -l` 출력이 비어 있고 `git diff --check`가 통과하는지 확인한다.
- follow-up 범위를 넘어 proto 계약이나 transport 구조를 불필요하게 다시 바꾸지 않았는지 확인한다.

## 검증 결과

### REVIEW_API-1 중간 검증
```bash
$ go test -v ./packages/config/... ./apps/edge/internal/transport/...
=== RUN   TestLoadEdge_ConsoleTimeoutDefault
--- PASS: TestLoadEdge_ConsoleTimeoutDefault (0.00s)
=== RUN   TestLoadEdge_ConsoleSessionDefaults
--- PASS: TestLoadEdge_ConsoleSessionDefaults (0.00s)
=== RUN   TestLoadEdge_ConsoleSessionOverride
--- PASS: TestLoadEdge_ConsoleSessionOverride (0.00s)
=== RUN   TestLoadEdge_ConsoleTimeoutOverride
--- PASS: TestLoadEdge_ConsoleTimeoutOverride (0.00s)
=== RUN   TestLoadEdge_ConsoleAgentFallbackFromLegacyModel
--- PASS: TestLoadEdge_ConsoleAgentFallbackFromLegacyModel (0.00s)
=== RUN   TestLoadEdge_CodexProfile
--- PASS: TestLoadEdge_CodexProfile (0.00s)
PASS
ok      iop/packages/config     0.005s
=== RUN   TestEdgeParserMap_NodeCommandResponse
--- PASS: TestEdgeParserMap_NodeCommandResponse (0.00s)
=== RUN   TestBuildConfigPayload_CLIArgsRoundtrip
--- PASS: TestBuildConfigPayload_CLIArgsRoundtrip (0.00s)
=== RUN   TestEdgeServerIntegration
--- PASS: TestEdgeServerIntegration (0.00s)
PASS
ok      iop/apps/edge/internal/transport        0.007s
```

### REVIEW_API-2 중간 검증
```bash
$ go test -v ./apps/node/internal/adapters/cli/status/... ./apps/node/internal/adapters/cli/...
=== RUN   TestCodexChecker
    codex_test.go:11: Skipping interactive TUI test by default
--- SKIP: TestCodexChecker (0.00s)
=== RUN   TestParseStatusOutput_CodexLimits
--- PASS: TestParseStatusOutput_CodexLimits (0.00s)
=== RUN   TestNewChecker_CodexUsesProfileCommand
--- PASS: TestNewChecker_CodexUsesProfileCommand (0.00s)
=== RUN   TestNewChecker_FallbackToCmdBase
--- PASS: TestNewChecker_FallbackToCmdBase (0.00s)
=== RUN   TestUnsupportedAgentReturnsError
--- PASS: TestUnsupportedAgentReturnsError (0.00s)
=== RUN   TestClaudeReturnsNotImplemented
--- PASS: TestClaudeReturnsNotImplemented (0.00s)
PASS
ok      iop/apps/node/internal/adapters/cli/status      0.003s
=== RUN   TestCLIHandleCommandUsageStatusUsesSelectedAgent
--- PASS: TestCLIHandleCommandUsageStatusUsesSelectedAgent (0.00s)
PASS
ok      iop/apps/node/internal/adapters/cli     0.004s
```

### REVIEW_API-3 중간 검증
```bash
$ go test -v ./apps/edge/cmd/edge
=== RUN   TestBuildRunRequest_SessionAndBackground
--- PASS: TestBuildRunRequest_SessionAndBackground (0.00s)
=== RUN   TestBuildRunRequest_EmptySessionNormalized
--- PASS: TestBuildRunRequest_EmptySessionNormalized (0.00s)
=== RUN   TestBuildRunRequest_DefaultTimeoutFallback
--- PASS: TestBuildRunRequest_DefaultTimeoutFallback (0.00s)
=== RUN   TestNormalizeConsoleSessionID
--- PASS: TestNormalizeConsoleSessionID (0.00s)
=== RUN   TestConsoleEventRouterRoutesRegisteredRun
--- PASS: TestConsoleEventRouterRoutesRegisteredRun (0.00s)
=== RUN   TestConsoleEventRouterPrintsUnregisteredRun
--- PASS: TestConsoleEventRouterPrintsUnregisteredRun (0.00s)
=== RUN   TestConsoleResponseStreamWritesBeforeFinish
--- PASS: TestConsoleResponseStreamWritesBeforeFinish (0.00s)
=== RUN   TestBuildNodeCommandRequest_StatusUsesCurrentTarget
--- PASS: TestBuildNodeCommandRequest_StatusUsesCurrentTarget (0.00s)
=== RUN   TestStatusWaitTimeout_UsesNormalizedRequestTimeout
--- PASS: TestStatusWaitTimeout_UsesNormalizedRequestTimeout (0.00s)
=== RUN   TestFormatUsageStatus_PrintsParsedLimits
--- PASS: TestFormatUsageStatus_PrintsParsedLimits (0.00s)
=== RUN   TestFormatUsageStatus_Error
--- PASS: TestFormatUsageStatus_Error (0.00s)
PASS
ok      iop/apps/edge/cmd/edge  0.004s
```

### REVIEW_API-4 중간 검증
```bash
$ gofmt -l apps/edge/cmd/edge/console.go apps/edge/cmd/edge/console_test.go apps/edge/internal/transport/server_test.go apps/node/internal/adapters/cli/status/codex.go apps/node/internal/adapters/cli/status/status.go apps/node/internal/node/node_test.go
(empty)

$ git diff --check
(empty)
```

### 최종 검증
```bash
$ go test ./...
...
ok      iop/apps/edge/cmd/edge  (cached)
ok      iop/apps/edge/internal/node     (cached)
ok      iop/apps/edge/internal/transport        (cached)
ok      iop/apps/node/internal/adapters (cached)
ok      iop/apps/node/internal/adapters/cli     (cached)
ok      iop/apps/node/internal/adapters/cli/lifecycle   (cached)
ok      iop/apps/node/internal/adapters/cli/oneshot     (cached)
ok      iop/apps/node/internal/adapters/cli/persistent  (cached)
ok      iop/apps/node/internal/adapters/cli/status      (cached)
ok      iop/apps/node/internal/bootstrap        (cached)
ok      iop/apps/node/internal/node     (cached)
ok      iop/apps/node/internal/router   (cached)
ok      iop/apps/node/internal/store    (cached)
ok      iop/apps/node/internal/transport        (cached)
ok      iop/packages/config     (cached)
...
PASS
```

---

## 코드리뷰 결과

- 종합 판정: PASS

### 차원별 평가

| 차원 | 평가 | 근거 |
|------|------|------|
| correctness | Pass | `configs/edge.yaml`의 codex profile이 실제 `codex` command와 `codex-json` output format으로 복원되었고, `/status` wait timeout도 보정된 request timeout을 사용한다. |
| completeness | Pass | `REVIEW_API-1`부터 `REVIEW_API-4`까지 이전 Required 항목이 모두 반영되었다. |
| test coverage | Pass | config/profile, status checker factory, CLI command handler, edge status timeout/formatter 테스트가 추가 또는 보강되었다. |
| API contract | Pass | follow-up 범위에서 proto/transport 계약을 불필요하게 다시 바꾸지 않았고 기존 command 경계를 유지했다. |
| code quality | Pass | `gofmt -l` 출력이 비어 있고 `git diff --check`가 통과한다. |
| plan deviation | Pass | 임시 integration test를 `packages/config/config_test.go`로 이관한 변경은 계획 범위 안의 테스트 정리로 판단된다. |
| verification trust | Pass | 제출된 검증을 주요 명령으로 재실행했고 결과가 코드 상태와 일치한다. |

### 발견된 문제

없음

### 리뷰 중 실행한 검증

```bash
$ rg -n "non-existent-codex|no such file or directory|likely not present|command: \"bash\"|codex-shell" apps/node/internal/adapters/cli configs packages apps/edge -S
(output 없음)

$ gofmt -l apps/edge/cmd/edge/console.go apps/edge/cmd/edge/console_test.go apps/edge/internal/transport/server_test.go apps/node/internal/adapters/cli/status/codex.go apps/node/internal/adapters/cli/status/status.go apps/node/internal/node/node_test.go apps/node/internal/adapters/cli/cli.go apps/node/internal/adapters/cli/cli_test.go apps/node/internal/adapters/cli/status/status_test.go packages/config/config_test.go
(output 없음)

$ git diff --check
(output 없음)

$ timeout 60s go test ./packages/config/... ./apps/edge/internal/transport/...
ok  	iop/packages/config	0.004s
ok  	iop/apps/edge/internal/transport	(cached)

$ timeout 90s go test ./apps/node/internal/adapters/cli/status/... ./apps/node/internal/adapters/cli/...
ok  	iop/apps/node/internal/adapters/cli/status	(cached)
ok  	iop/apps/node/internal/adapters/cli	(cached)
?   	iop/apps/node/internal/adapters/cli/internal/testutil	[no test files]
ok  	iop/apps/node/internal/adapters/cli/lifecycle	2.267s
ok  	iop/apps/node/internal/adapters/cli/oneshot	0.287s
ok  	iop/apps/node/internal/adapters/cli/persistent	63.249s

$ timeout 60s go test ./apps/edge/cmd/edge
ok  	iop/apps/edge/cmd/edge	(cached)

$ make proto
protoc \
	--go_out=. \
	--go_opt=module=iop \
	--proto_path=. \
	proto/iop/runtime.proto \
	proto/iop/node.proto \
	proto/iop/control.proto \
	proto/iop/job.proto

$ timeout 180s go test ./...
ok  	iop/apps/edge/cmd/edge	(cached)
ok  	iop/apps/edge/internal/node	(cached)
ok  	iop/apps/edge/internal/transport	(cached)
ok  	iop/apps/node/internal/adapters	(cached)
ok  	iop/apps/node/internal/adapters/cli	(cached)
ok  	iop/apps/node/internal/adapters/cli/lifecycle	(cached)
ok  	iop/apps/node/internal/adapters/cli/oneshot	(cached)
ok  	iop/apps/node/internal/adapters/cli/persistent	(cached)
ok  	iop/apps/node/internal/adapters/cli/status	(cached)
ok  	iop/apps/node/internal/bootstrap	(cached)
ok  	iop/apps/node/internal/node	(cached)
ok  	iop/apps/node/internal/router	(cached)
ok  	iop/apps/node/internal/store	(cached)
ok  	iop/apps/node/internal/transport	(cached)
ok  	iop/packages/config	(cached)
```

### 다음 단계

PASS: active `CODE_REVIEW.md`와 `PLAN.md`를 아카이브하고 `complete.log`를 작성해 작업을 종료한다.
