<!-- task=m-control-plane-jenkins-menu-ia-code-sync/03+01_executions_ops plan=0 tag=JENKINS_IA_OPS -->

# Code Review Reference - JENKINS_IA_OPS

> **[IMPLEMENTING AGENT — READ FIRST] Filling in this file is the mandatory final step of implementation.**
> The task is NOT complete until every implementation-owned section below is filled in.
> Complete the `구현 체크리스트`; the final checklist item is mandatory before saving.
> Fill implementation-owned sections, then stop with active files in place and report ready for review.
> If implementation is blocked by a selected Milestone `구현 잠금 > 결정 필요` item, fill `사용자 리뷰 요청` with linked evidence and stop with active files in place; code-review decides whether to write `USER_REVIEW.md`.
> Do not ask the user directly, present choices in chat, or call `request_user_input` during implementation.
> Finalization is review-agent-only.

## 개요

date=2026-07-03
task=m-control-plane-jenkins-menu-ia-code-sync/03+01_executions_ops, plan=0, tag=JENKINS_IA_OPS

## Roadmap Targets

- Milestone: `agent-roadmap/phase/control-plane-product-surface/milestones/control-plane-jenkins-menu-ia-code-sync.md`
- Task ids:
  - `execution-ops-menu-sync`: executions/runners/settings 화면이 `Pipeline Overview`, `Console Output`, `Artifacts`, `Build History`, `Nodes/Agents`, `Manage OTO` 중심으로 동기화된다.
  - `preview-deploy`: 동기화된 Flutter web build를 원격 preview에 배포한다.
- Completion mode: check-on-pass

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

> **[REVIEW AGENT ONLY]** 아래 종결 절차는 코드리뷰 에이전트 전용이다.

각 항목의 구현을 실제 소스 파일과 대조하고, `검증 결과` 섹션의 출력이 코드와 일치하는지 확인하세요.

---

## 구현 항목별 완료 여부

| 항목 | 완료 여부 |
|------|---------|
| [JENKINS_IA_OPS-1] Pipeline Graph Run Detail | [x] |
| [JENKINS_IA_OPS-2] Nodes And Agents Runners Surface | [x] |
| [JENKINS_IA_OPS-3] Manage OTO Settings | [x] |
| [JENKINS_IA_OPS-4] Preview Deployment Smoke | [x] |

## 구현 체크리스트

- [x] [JENKINS_IA_OPS-1] executions run detail을 Pipeline Graph View/Stage View 및 run-context left task menu 중심 구조로 개편한다.
- [x] [JENKINS_IA_OPS-2] runners를 Jenkins Nodes/Agents style 운영 목록으로 개편한다.
- [x] [JENKINS_IA_OPS-3] settings fallback을 Manage OTO category 구조로 개편한다.
- [x] [JENKINS_IA_OPS-4] console/client tests를 갱신하고 원격 preview를 재배포한다.
- [x] `cd packages/flutter/oto_console && flutter analyze && flutter test`, `cd apps/client && flutter analyze && flutter test`, `git diff --check`, preview `curl -I`를 실행한다.
- [x] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

## Agent UI Completion

- Mode: review-pass-status-update
- Agent UI docs:
  - `agent-ui/definition/index.md`
  - `agent-ui/definition/views/index.md`
  - `agent-ui/definition/components/index.md`
- Actual code evidence:
  - [x] `packages/flutter/oto_console/lib/src/oto_executions_surface.dart`: `_buildExecutionDetail`가 `_RunTaskMenu`(Console Output/Pipeline Overview/Artifacts/Build History 좌측 task menu)와 `_PipelineStageGraph`(`Stage Graph`, Checkout/Build/Package/Publish 상태 chip, run state 기반 secondary note)를 primary region으로 렌더한다. `Stage summary unavailable` 단독 placeholder는 제거했고, 기존 Logs Preview pane은 `Console Output` 타이틀로 통합했다.
  - [x] `packages/flutter/oto_console/lib/src/oto_runners_surface.dart`: `_NodesTableHeader`(Nodes/Executor/Current job/Current run/Manage 컬럼 헤더)와 `_NodeTableRow`(node id/alias, executor status, current job/run, manage 아이콘, 기존 message/self-update panel 유지)로 Runners를 Nodes/Agents 운영 목록으로 재구성했다.
  - [x] `packages/flutter/oto_console/lib/src/oto_console_shell.dart`: settings fallback을 `_ManageOtoSettingsSurface`(`Manage OTO` 타이틀 + `System`/`Security` category card)로 교체했다. System 카드는 기존 Runtime endpoints(HTTP API/Wire URL) 값을, Security 카드는 기존 Browser policy(Browser API policy, CORS 안내) 값을 그대로 유지한다.
- Implementation verification evidence:
  - [x] `cd packages/flutter/oto_console && flutter analyze && flutter test`: `No issues found!` / `00:01 +14: All tests passed!`
  - [x] `cd apps/client && flutter analyze && flutter test`: `No issues found!` / `00:03 +27: All tests passed!`
  - [x] `curl -I http://toki-labs.com:13020/`: `HTTP/1.0 200 OK` (Server: SimpleHTTP/0.6 Python/3.9.6)
- Status updates requested on PASS:
  - [x] `agent-ui/definition/views/index.md`: `executions`, `runners`, `settings` Jenkins IA criteria `계획` -> `구현됨`
  - [x] `agent-ui/definition/components/index.md`: ops component criteria `계획` -> `구현됨`
- Review finalization:
  - [x] Review agent updated the listed agent-ui docs and code evidence.
  - [x] Review agent ran `validate-agent-ui scope=jenkins-ia-executions-ops` after the status/evidence update.

## 코드리뷰 전용 체크리스트

> **[REVIEW AGENT ONLY]** 이 체크리스트는 코드리뷰 에이전트만 사용한다.

- [x] `코드리뷰 결과`에 `PASS`, `WARN`, `FAIL` 중 하나의 판정을 append한다.
- [x] active review/plan 파일을 `.log`로 아카이브한다.
- [x] PASS이면 `complete.log` 작성 후 `agent-task/archive/YYYY/MM/m-control-plane-jenkins-menu-ia-code-sync/03+01_executions_ops/`로 이동한다.
- [x] PASS split 작업이면 빈 active parent를 제거하거나 남은 sibling 때문에 유지했다고 확인한다.
- [ ] WARN/FAIL이면 후속 active plan/review 또는 정당한 `USER_REVIEW.md`를 작성한다.

## 계획 대비 변경 사항

- `rsync`가 로컬 환경(sandbox)에 없어 계획의 `rsync -a --delete` 대신 `tar czf - . | ssh ... tar xzf - -C "$preview_dir"`로 동일한 결과(신규 preview dir에 build/web 전체 배포)를 만들었다. 목적지 디렉터리는 계획대로 새 `oto-ui-preview-<timestamp>-jenkins-ia` 경로이며 기존 checkout은 건드리지 않았다.
- `apps/client/test/widget_test.dart:1729` 부근 실행 시 `_DetailPane` 헤더 Row(`Row(mainAxisAlignment: spaceBetween)`)가 새 run-context 좌측 task menu 폭(168px)만큼 줄어든 콘텐츠 폭에서 `RenderFlex` overflow를 냈다. `packages/flutter/oto_console/lib/src/oto_executions_surface.dart`의 `_DetailPane` title을 `Expanded(overflow: ellipsis)`로 감싸 action 버튼과 공존 가능하게 수정했다(계획에 명시되지 않은 부수 수정, `_DetailPane` 자체는 계획 대상 파일 범위 안).
- Settings Manage OTO 카테고리는 계획 체크리스트가 예시로 든 `System/Security/Tools/Nodes/Browser policy` 중 실제 데이터가 있는 `System`(Runtime endpoints)과 `Security`(Browser policy 하위 그룹)만 구현했다. `Tools`/`Nodes`는 OTO Core에 대응 데이터가 없어 뼈대만 있는 placeholder 카테고리를 추가하지 않았다(범위 결정 근거의 "OTO contract에 맞는 항목만 표시" 원칙 적용). 필요한 텍스트(`Manage OTO`/`System`/`Security`/`Browser policy`)는 모두 노출된다.
- Runners 테이블은 계획의 "Nodes, Executor, Current job, Current run, Manage" 컬럼 헤더를 그대로 추가했지만, `apps/client/test/widget_test.dart`가 OPS-2 범위 밖이라 기존 row 텍스트(`ID: $runnerID`, `Alias: ...`, `Message: ...`, `Job: ...`/`Execution: ...`)는 그대로 보존했다. `Manage` 컬럼은 아이콘만 표시하고 기존 Self Update 폼은 행 하단에 그대로 유지했다(플랜이 요구한 콜백/검증 로직 변경 없음).

## 주요 설계 결정

- Run-context 좌측 task menu(`_RunTaskMenu`)는 별도 per-item view가 없어 Jenkins build 페이지 사이드바처럼 정적 라벨 목록으로 구현했다(클릭 동작 없음). Core에 stage/console/artifact를 개별 뷰로 분리할 데이터 소스가 없는 현재 범위에서 과도한 상태 관리를 피하기 위한 선택이다.
- Stage Graph는 실제 stage 데이터가 없으므로 `Checkout/Build/Package/Publish` 고정 스켈레톤을 실행 `state`(succeeded/failed/running/canceled/queued)에서 결정적으로 매핑했다. `Stage summary unavailable`는 제거하고 그래프 하단의 secondary note(“Per-stage telemetry is not reported yet …”)로 대체했다.
- Manage OTO Security 카드는 기존 Browser policy 상세 그룹(값 불변)을 그대로 재사용해 `Security`(카테고리)와 `Browser policy`(하위 그룹) 두 라벨이 자연스럽게 함께 노출되도록 구성했다.

## 사용자 리뷰 요청

_기본값은 `없음`이다. 구현 중 새 결정이 필요해 보여도 직접 질문하거나 선택지를 제시하거나 `request_user_input`을 호출하지 않는다. 이 섹션은 선택된 Milestone `구현 잠금 > 결정 필요` 항목이 실구현을 차단할 때만 채운다. 외부 환경/secret/서비스 준비, 검증 증거 공백, 반복 실패, 일반 범위 조정은 사용자 리뷰 요청이 아니며 `검증 결과`, `계획 대비 변경 사항`, 또는 code-review의 일반 follow-up plan으로 처리한다._

- 상태: 없음
- 사유 유형: 없음
- 연결 대상: 없음
- 결정 필요: 없음
- 차단 근거: 없음
- 실행한 검증/명령: 없음
- 자동 후속 불가 이유: 없음
- 재개 조건: 없음

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

- `Stage summary unavailable` 단독 placeholder가 사라지고 `Stage Graph`와 run-context left task menu가 primary run detail이 되었는지 확인한다.
- Runners가 generic card list가 아니라 Nodes/Agents operational list로 보이는지 확인한다.
- Settings fallback이 Manage OTO category menu/surface인지 확인한다.
- Preview deployment가 dirty remote checkout을 source로 사용하지 않았는지 확인한다.

## 검증 결과

### JENKINS_IA_OPS-1 중간 검증
```bash
$ cd packages/flutter/oto_console && flutter test test/oto_console_test.dart
00:01 +9: OtoExecutionsSurface renders loading/empty/error/data states and expanded detail
00:01 +14: All tests passed!
```
(첫 실행 시 apps/client 쪽에서 좌측 task menu로 줄어든 폭 때문에 `_DetailPane` 헤더 Row가 RenderFlex overflow를 냈다. `_DetailPane` title을 `Expanded(overflow: ellipsis)`로 수정한 뒤 재실행하여 통과했다 — 상세는 `계획 대비 변경 사항` 참조.)

### JENKINS_IA_OPS-2 중간 검증
```bash
$ cd packages/flutter/oto_console && flutter test test/oto_console_test.dart
00:00 +6: OtoRunnersSurface renders data state with runners list
00:01 +7: OtoRunnersSurface renders runner action states
00:01 +14: All tests passed!
```

### JENKINS_IA_OPS-3 중간 검증
```bash
$ cd packages/flutter/oto_console && flutter test test/oto_console_test.dart
00:00 +2: renders section surfaces with empty states
00:01 +14: All tests passed!
```

### JENKINS_IA_OPS-4 중간 검증
```bash
$ cd apps/client && flutter build web --dart-define=OTO_SERVER_HTTP_URL=http://toki-labs.com:18020
Compiling lib/main.dart for the Web...                             31.9s
✓ Built build/web

$ preview_dir="/Users/toki/agent-work/oto-ui-preview-20260703142823-jenkins-ia"
$ ssh toki@toki-labs.com "mkdir -p '$preview_dir'"
(성공, 출력 없음)

# 로컬 sandbox에 rsync가 없어 tar 파이프로 대체(계획 대비 변경 사항 참조):
$ cd apps/client/build/web && tar czf - . | ssh toki@toki-labs.com "tar xzf - -C '$preview_dir'"
$ ssh toki@toki-labs.com "ls '$preview_dir' | head -5"
assets
canvaskit
favicon.png
flutter_bootstrap.js
flutter_service_worker.js

$ ssh toki@toki-labs.com "pkill -f 'python3 -m http.server 13020' || true; sleep 1; cd '$preview_dir' && nohup python3 -m http.server 13020 >/tmp/oto-ui-preview.log 2>&1 & disown; sleep 1; echo started"
started

$ curl -I http://toki-labs.com:13020/
HTTP/1.0 200 OK
Server: SimpleHTTP/0.6 Python/3.9.6
Date: Fri, 03 Jul 2026 14:28:47 GMT
Content-type: text/html
Content-Length: 1540
```

### 최종 검증
```bash
$ find agent-task/archive/2026/07/m-control-plane-jenkins-menu-ia-code-sync/01_definition_guardrails -name "complete.log"
agent-task/archive/2026/07/m-control-plane-jenkins-menu-ia-code-sync/01_definition_guardrails/complete.log
# (predecessor 01은 이미 archive로 이동되어 완료되었음 — 02+01_shell_jobs도 archive에서 complete.log 확인됨)

$ cd packages/flutter/oto_console && flutter analyze && flutter test
Analyzing oto_console...
No issues found! (ran in 3.4s)
00:01 +14: All tests passed!

$ cd apps/client && flutter analyze && flutter test
Analyzing client...
No issues found! (ran in 2.4s)
00:03 +27: All tests passed!

$ git diff --check
(출력 없음, exit code 0)

$ cd apps/client && flutter build web --dart-define=OTO_SERVER_HTTP_URL=http://toki-labs.com:18020
✓ Built build/web

$ curl -I http://toki-labs.com:13020/
HTTP/1.0 200 OK
```

---

> **[IMPLEMENTING AGENT — BEFORE SAVING] Have you filled in every implementation-owned section: completion table, implementation checklist, changes from plan, design decisions, and verification output?**

## 코드리뷰 결과

- 종합 판정: PASS
- 차원별 평가:
  - correctness: Pass
  - completeness: Pass
  - test coverage: Pass
  - API contract: Pass
  - code quality: Pass
  - implementation deviation: Pass
  - verification trust: Pass
  - spec conformance: Pass (Roadmap Targets 확인, SDD 불필요)
- 발견된 문제: 없음
- 검증 근거:
  - `git diff --check`: 출력 없음, exit code 0
  - `cd packages/flutter/oto_console && flutter analyze && flutter test`: `No issues found!`, `+14: All tests passed!`
  - `cd apps/client && flutter analyze && flutter test`: `No issues found!`, `+27: All tests passed!`
  - 원격 runner 임시 작업트리 `/Users/toki/agent-work/oto-review-20260703144007-jenkins-ia`: console/client analyze/test 및 `flutter build web --dart-define=OTO_SERVER_HTTP_URL=http://toki-labs.com:18020` PASS
  - `curl -I --max-time 15 http://toki-labs.com:13020/`: `HTTP/1.0 200 OK`
  - `validate-agent-ui scope=jenkins-ia-executions-ops`: PASS (필수 root 문서 존재, USER_REVIEW 없음, code evidence 경로 존재, listed view/component status 반영 확인)
- 다음 단계: PASS이므로 active plan/review를 `.log`로 아카이브하고 `complete.log` 작성 후 task directory를 archive로 이동한다.
