<!-- task=m-control-plane-jenkins-menu-ia-code-sync/02+01_shell_jobs plan=0 tag=JENKINS_IA_SHELL -->

# Plan - Jenkins IA Shell And Jobs

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

`CODE_REVIEW-cloud-G07.md`의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채우는 것이 구현의 마지막 단계다. 구현 후 active 파일을 유지하고 리뷰 준비만 보고한다. 선택된 Milestone `구현 잠금 > 결정 필요` 항목이 실구현을 차단할 때만 리뷰 스텁의 `사용자 리뷰 요청` 섹션을 채우고 멈춘다. 구현 중 직접 사용자에게 질문하거나 선택지를 제시하거나 `request_user_input`, `USER_REVIEW.md`, `complete.log`, archive 이동을 수행하지 않는다.

## 배경

현재 shell은 Jenkins의 통합 header/breadcrumb/action navigation보다 60px rail 중심이다. Pipelines 화면도 Jenkins dashboard job table/New Item 흐름보다 카드형 리스트와 inline create panel에 가깝다. 사용자 결정으로 메뉴 구조는 OTO에 적용 가능한 Jenkins 모델만 1차 적용하는 것으로 확정되었으므로, 01 정의서 guardrail 완료 후 shell과 jobs 화면을 적용 가능 menu model 중심으로 개편한다.

## 사용자 리뷰 요청 흐름

사용자 리뷰 요청은 선택된 Milestone lock 결정이 구현을 막을 때만 active `CODE_REVIEW-cloud-G07.md`의 `사용자 리뷰 요청` 섹션에 기록한다. 구현 에이전트는 직접 사용자 프롬프트를 띄우지 않는다.

## Roadmap Targets

- Milestone: `agent-roadmap/phase/control-plane-product-surface/milestones/control-plane-jenkins-menu-ia-code-sync.md`
- Task ids:
  - `shell-menu-sync`: shell/global menu와 pipelines/jobs 화면이 `New Item`, `Pipelines`, `Build History`, job `Status`, job `Build History`, `Stages` 중심으로 동기화된다.
- Completion mode: check-on-pass

## 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`
- Required code evidence:
  - `packages/flutter/oto_console/lib/src/oto_console_shell.dart`: Jenkins-style header, breadcrumb, dashboard left menu, primary action/task navigation evidence
  - `packages/flutter/oto_console/lib/src/oto_jobs_surface.dart`: dashboard job table/list, build queue/history/action evidence
- Required implementation verification:
  - `cd packages/flutter/oto_console && flutter analyze && flutter test`: PASS expected before review
  - `cd apps/client && flutter analyze && flutter test`: PASS expected before review
- Review finalization validation:
  - `validate-agent-ui scope=jenkins-ia-shell-jobs`: PASS expected after status/evidence update
- Status updates on PASS:
  - `agent-ui/definition/index.md`: Jenkins IA shell/jobs gate evidence updated
  - `agent-ui/definition/views/index.md`: `pipelines` shell/jobs criteria `계획` -> `구현됨`
  - `agent-ui/definition/components/index.md`: `console-shell`, `console-rail`, `record-list`, `job-create-form`, `status-badge` criteria `계획` -> `구현됨`

## 분석 결과

### 읽은 파일

- `agent-roadmap/current.md`
- `agent-roadmap/phase/control-plane-product-surface/PHASE.md`
- `agent-roadmap/phase/control-plane-product-surface/milestones/control-plane-jenkins-menu-ia-code-sync.md`
- `agent-test/local/rules.md`
- `agent-test/local/framework-smoke.md`
- `agent-ui/definition/index.md`
- `agent-ui/definition/views/index.md`
- `agent-ui/definition/components/index.md`
- `packages/flutter/oto_console/lib/src/oto_console_shell.dart`
- `packages/flutter/oto_console/lib/src/oto_jobs_surface.dart`
- `packages/flutter/oto_console/lib/src/oto_console_contract.dart`
- `packages/flutter/oto_console/lib/src/oto_console_models.dart`
- `packages/flutter/oto_console/lib/oto_console.dart`
- `packages/flutter/oto_console/pubspec.yaml`
- `packages/flutter/oto_console/test/oto_console_test.dart`
- `apps/client/lib/src/app/oto_client_app.dart`
- `apps/client/pubspec.yaml`
- `apps/client/test/widget_test.dart`

### SDD 기준

Milestone: `agent-roadmap/phase/control-plane-product-surface/milestones/control-plane-jenkins-menu-ia-code-sync.md`. SDD: 불필요. 사유: 기존 Flutter/agent-ui IA 정렬이며 새 API/schema/proto/config/env 계약 또는 외부 provider 쓰기 경계를 만들지 않는다.

### 테스트 환경 규칙

test_env는 `local`이다. `agent-test/local/rules.md`, `agent-test/local/framework-smoke.md`를 적용한다. 원격 runner checkout은 dirty/HEAD mismatch 상태이므로 이 단계는 현재 checkout에서 구현하고, Flutter console/client analyze/test를 실행한 뒤 03에서 remote preview artifact deployment를 수행한다.

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

- Shell: [packages/flutter/oto_console/test/oto_console_test.dart](/config/workspace/oto/packages/flutter/oto_console/test/oto_console_test.dart:52)는 `OtoConsoleShell` render와 Agent tooltip만 확인한다.
- Section navigation: [packages/flutter/oto_console/test/oto_console_test.dart](/config/workspace/oto/packages/flutter/oto_console/test/oto_console_test.dart:91)는 empty state만 순회한다.
- Jobs: [packages/flutter/oto_console/test/oto_console_test.dart](/config/workspace/oto/packages/flutter/oto_console/test/oto_console_test.dart:387)는 job name/status/id/link만 확인한다.
- Menu model: 기존 테스트는 `New Item`, `Build History`, `Manage OTO`, job-context `Status` 메뉴를 단언하지 않는다.

### 심볼 참조

공개 symbol rename/remove는 계획하지 않는다. 내부 private widget 추가/교체만 수행한다.

### 분할 판단

dependent subtask `02+01_shell_jobs`이며 predecessor index `01`은 `agent-task/m-control-plane-jenkins-menu-ia-code-sync/01_definition_guardrails/complete.log`로 만족되어야 한다. 이 파일 작성 시점에는 predecessor가 아직 active/pending이므로 구현 시작 전 확인한다.

### 범위 결정 근거

이 단계는 `oto_console_shell.dart`, `oto_jobs_surface.dart`, 관련 console/client widget tests에 한정한다. Global menu의 `New Item`, `Pipelines`, `Build History`, job-context menu의 `Status`, selected job history/stage link까지만 02 범위로 둔다. Existing job `Build Now`, `Configure`, `People`, `Changes`, `Replay`, `Pipeline Syntax`는 1차 적용에서 제외한다. Executions run menu, runners, settings는 03에서 처리한다. Core API, view model field 확장, 권한/audit UI는 제외한다.

### 빌드 등급

`cloud-G07`. Jenkins IA 외부 reference와 broad widget 구조 변경이 결합되어 local-only 코드 패턴보다 제품 구조 판단이 중요하다.

## 구현 체크리스트

- [ ] [JENKINS_IA_SHELL-1] shell을 통합 header/breadcrumb/action/task navigation과 Jenkins Dashboard-level left menu 구조로 개편한다.
- [ ] [JENKINS_IA_SHELL-2] pipelines/jobs 화면을 Jenkins dashboard job table/New Item/Build History 및 적용 가능한 job-context left task menu 구조로 개편한다.
- [ ] [JENKINS_IA_SHELL-3] shell/jobs widget tests와 app host regression tests를 Jenkins IA primitive 기준으로 갱신한다.
- [ ] `cd packages/flutter/oto_console && flutter analyze && flutter test`, `cd apps/client && flutter analyze && flutter test`, `git diff --check`를 실행한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

### [JENKINS_IA_SHELL-1] Shell Header And Breadcrumb IA

#### 문제

[packages/flutter/oto_console/lib/src/oto_console_shell.dart](/config/workspace/oto/packages/flutter/oto_console/lib/src/oto_console_shell.dart:57)는 `SafeArea > Row`에서 rail과 page frame을 나란히 둔다. [packages/flutter/oto_console/lib/src/oto_console_shell.dart](/config/workspace/oto/packages/flutter/oto_console/lib/src/oto_console_shell.dart:227)는 page header에 icon + label만 둔다. [packages/flutter/oto_console/lib/src/oto_console_shell.dart](/config/workspace/oto/packages/flutter/oto_console/lib/src/oto_console_shell.dart:312)는 60px rail을 primary navigation으로 만든다.

#### 해결 방법

상단 header를 primary app context로 승격한다. Header에는 `OTO / <section group> / <section label>` breadcrumb, section action strip, selected section status/context를 둔다. 좌측 영역은 적용 가능한 Jenkins Dashboard-level menu로 맞춰 `New Item`, `Pipelines`, `Build History`를 알아볼 수 있게 둔다. `Manage OTO`, `Nodes`, `Artifacts`는 03 범위와 함께 global menu에 합류할 수 있게 shell 구조를 열어둔다.

Before:

```dart
57 body: SafeArea(
58   child: Row(
61     _OtoConsoleRail(...),
67     child: _ConsolePageFrame(...),
```

After:

```dart
body: SafeArea(
  child: _JenkinsConsoleFrame(
    descriptor: descriptor,
    selected: _section,
    onSelect: _select,
    child: _buildContent(theme),
  ),
)
```

#### 수정 파일 및 체크리스트

- [ ] `packages/flutter/oto_console/lib/src/oto_console_shell.dart`: `_PageHeader`를 breadcrumb/action-aware header로 교체한다.
- [ ] `packages/flutter/oto_console/lib/src/oto_console_shell.dart`: rail을 적용 가능한 Jenkins Dashboard-level left menu로 재배치하고 `New Item`, `Pipelines`, `Build History` entry를 노출한다.
- [ ] `packages/flutter/oto_console/lib/src/oto_console_shell.dart`: 03에서 `Nodes`, `Artifacts`, `Manage OTO` entry를 추가할 수 있도록 menu model을 확장 가능하게 둔다.

#### 테스트 작성

`packages/flutter/oto_console/test/oto_console_test.dart`에 shell test를 추가/수정한다. Assertion: `OTO`, `New Item`, `Build History`, `Pipelines`, 또는 정의서에서 고정한 breadcrumb/action labels가 렌더된다. 기존 Agent navigation callback은 유지한다.

#### 중간 검증

```bash
cd packages/flutter/oto_console && flutter test test/oto_console_test.dart
```

예상: shell/header/jobs 관련 widget tests PASS.

### [JENKINS_IA_SHELL-2] Jenkins Dashboard Jobs Surface

#### 문제

[packages/flutter/oto_console/lib/src/oto_jobs_surface.dart](/config/workspace/oto/packages/flutter/oto_console/lib/src/oto_jobs_surface.dart:48)는 maxWidth 820 카드형 body를 만들고, [packages/flutter/oto_console/lib/src/oto_jobs_surface.dart](/config/workspace/oto/packages/flutter/oto_console/lib/src/oto_jobs_surface.dart:299)는 `ListView.separated` record rows로 job을 보여준다. Jenkins dashboard에서 익숙한 job row/table, build history/queue context, New Item 진입 구조가 1차 구조가 아니다.

#### 해결 방법

Jobs surface를 dashboard 형식으로 바꾼다. 상단 또는 좌측 context에는 `New Item`/create action과 `Build Queue`/`Build History` context를 둔다. Job 선택/row context에는 OTO에 바로 적용 가능한 Jenkins job menu인 `Status`, job `Build History`, `Stages` link만 노출한다. Data state는 `Name`, `Status`, `Last Run`, `Updated`, `Actions`가 있는 table-like list로 구성하고 execution link는 `Last Run` 또는 row action에 둔다.

Before:

```dart
299 return ListView.separated(
344   return _RecordRow(
345     title: job.name,
346     subtitle: 'Job ID: ${job.jobID}',
```

After:

```dart
return _JenkinsJobDashboard(
  jobs: jobs,
  onExecutionTap: widget.onExecutionTap,
  createForm: _buildJobCreateForm(context, theme),
);
```

#### 수정 파일 및 체크리스트

- [ ] `packages/flutter/oto_console/lib/src/oto_jobs_surface.dart`: `_JenkinsJobDashboard`, `_JobTableHeader`, `_JobTableRow`, `_BuildQueuePanel`, `_JobTaskMenu` 또는 동등 구조를 추가한다.
- [ ] `_JobTaskMenu`는 `Status`, `Build History`, `Stages`만 포함하고 `Build Now`/`Configure`는 만들지 않는다.
- [ ] 기존 `onExecutionTap` callback과 create form validation/action state를 유지한다.
- [ ] empty/error/loading state를 dashboard shell 안에서 깨지지 않게 배치한다.

#### 테스트 작성

`packages/flutter/oto_console/test/oto_console_test.dart` jobs test를 수정한다. Assertion: `New Item`, `Build Queue`, `Build History`, `Status`, `Stages`, table header `Name`, `Status`, `Last Run`이 보이고 execution tap callback이 유지된다.

#### 중간 검증

```bash
cd packages/flutter/oto_console && flutter test test/oto_console_test.dart
```

예상: jobs dashboard and callback tests PASS.

### [JENKINS_IA_SHELL-3] Host Regression

#### 문제

[apps/client/lib/src/app/oto_client_app.dart](/config/workspace/oto/apps/client/lib/src/app/oto_client_app.dart:652)는 console package surface를 mount하므로 shell/jobs label 변경이 client widget tests를 깨뜨릴 수 있다. [apps/client/test/widget_test.dart](/config/workspace/oto/apps/client/test/widget_test.dart:1712)는 old Pipelines text assumptions를 가진다.

#### 해결 방법

client tests를 새 Jenkins IA label에 맞추되, data fetching/write callback assertions는 유지한다. Host app source 변경은 필요한 label adaptation이 있을 때만 수행한다.

#### 수정 파일 및 체크리스트

- [ ] `apps/client/test/widget_test.dart`: shell/jobs visible labels를 갱신한다.
- [ ] `apps/client/lib/src/app/oto_client_app.dart`: 변경 필요 시에만 mount props를 조정한다.

#### 테스트 작성

기존 client widget tests를 수정한다. 새 테스트 파일은 만들지 않는다.

#### 중간 검증

```bash
cd apps/client && flutter test test/widget_test.dart
```

예상: host widget regressions PASS.

## 의존 관계 및 구현 순서

구현 시작 전 `agent-task/m-control-plane-jenkins-menu-ia-code-sync/01_definition_guardrails/complete.log` 존재를 확인한다. 02는 03과 병렬 가능하다.

## 수정 파일 요약

| 파일 | 항목 |
|------|------|
| `packages/flutter/oto_console/lib/src/oto_console_shell.dart` | JENKINS_IA_SHELL-1 |
| `packages/flutter/oto_console/lib/src/oto_jobs_surface.dart` | JENKINS_IA_SHELL-2 |
| `packages/flutter/oto_console/test/oto_console_test.dart` | JENKINS_IA_SHELL-1, JENKINS_IA_SHELL-2 |
| `apps/client/test/widget_test.dart` | JENKINS_IA_SHELL-3 |
| `apps/client/lib/src/app/oto_client_app.dart` | JENKINS_IA_SHELL-3, only if required |
| `agent-ui/definition/index.md` | JENKINS_IA_SHELL-1, JENKINS_IA_SHELL-2 |
| `agent-ui/definition/views/index.md` | JENKINS_IA_SHELL-1, JENKINS_IA_SHELL-2 |
| `agent-ui/definition/components/index.md` | JENKINS_IA_SHELL-1, JENKINS_IA_SHELL-2 |

## 최종 검증

```bash
test -f agent-task/m-control-plane-jenkins-menu-ia-code-sync/01_definition_guardrails/complete.log
cd packages/flutter/oto_console && flutter analyze && flutter test
cd apps/client && flutter analyze && flutter test
git diff --check
```

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