240 lines
11 KiB
Text
240 lines
11 KiB
Text
<!-- 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`를 작성해 작업을 종료한다.
|