diff --git a/agent-task/jenkins_compatibility_boundary/01_core_adapter/CODE_REVIEW-cloud-G07.md b/agent-task/jenkins_compatibility_boundary/01_core_adapter/CODE_REVIEW-cloud-G07.md new file mode 100644 index 0000000..2e7c477 --- /dev/null +++ b/agent-task/jenkins_compatibility_boundary/01_core_adapter/CODE_REVIEW-cloud-G07.md @@ -0,0 +1,124 @@ + + +# Code Review Reference - REFACTOR + +> **[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. +> Finalization (`코드리뷰 결과`, log rename, `complete.log`, archive moves, `코드리뷰 전용 체크리스트`) is review-agent-only, even after compaction/resume. +> Follow the ownership table at the bottom of this file for which sections you own. + +## 개요 + +date=2026-05-22 +task=jenkins_compatibility_boundary/01_core_adapter, plan=0, tag=REFACTOR + +## 이 파일을 읽는 리뷰 에이전트에게 + +> **[REVIEW AGENT ONLY]** 아래 종결 절차는 코드리뷰 에이전트 전용이다. 구현 에이전트는 이 섹션을 실행하지 않는다. + +각 항목의 구현을 실제 소스 파일과 대조하고, `검증 결과` 섹션의 출력이 코드와 일치하는지 확인하세요. +리뷰 완료는 아래 순서까지 끝난 상태를 의미합니다. + +1. 판정을 append한다. +2. `CODE_REVIEW-cloud-G07.md` -> `code_review_cloud_G07_0.log`, `PLAN-cloud-G07.md` -> `plan_cloud_G07_0.log`로 아카이브한다. +3. PASS이면 `agent-ops/skills/common/code-review/templates/complete-log-template.md` 기준으로 `complete.log`를 작성하고 active `.md` 파일을 남기지 않는다. +4. PASS이면 active task 디렉터리 `agent-task/jenkins_compatibility_boundary/01_core_adapter/`를 `agent-task/archive/YYYY/MM/jenkins_compatibility_boundary/01_core_adapter/`로 이동한다. +5. 적용 가능한 `코드리뷰 전용 체크리스트` 항목을 최종 `.log` 위치에서 체크한 뒤 보고한다. + +--- + +## 구현 항목별 완료 여부 + +| 항목 | 완료 여부 | +|------|---------| +| [REFACTOR-1] Jenkins 환경 변수 수집 책임을 adapter로 분리 | [ ] | +| [REFACTOR-2] mode-neutral default workspace 정리 | [ ] | + +## 구현 체크리스트 + +- [ ] REFACTOR-1 Jenkins 환경 변수 수집 책임을 `DataComposerJenkins.compose()` 밖의 명시적 adapter로 분리한다. +- [ ] REFACTOR-2 file/scheduler/test 모드가 Jenkins 이름의 기본 데이터와 `Platform.environment['WORKSPACE']!`에 직접 기대지 않도록 기본 workspace 경계를 정리한다. +- [ ] 모든 중간 검증과 최종 검증을 실행하고 실제 stdout/stderr를 `CODE_REVIEW-cloud-G07.md`에 기록한다. +- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다. + +## 코드리뷰 전용 체크리스트 + +> **[REVIEW AGENT ONLY]** 이 체크리스트는 코드리뷰 에이전트만 사용한다. +> 구현 에이전트는 이 섹션을 수정하거나 체크하지 않는다. + +- [ ] `코드리뷰 결과`에 `PASS`, `WARN`, `FAIL` 중 하나의 판정을 append한다. +- [ ] 판정과 `차원별 평가`, Required/Suggested/Nit 분류가 서로 일치한다. +- [ ] active `CODE_REVIEW-*-G??.md`를 `code_review_{review_lane}_GNN_N.log`로 아카이브한다. +- [ ] active `PLAN-*-G??.md`를 `plan_{build_lane}_GNN_M.log`로 아카이브한다. +- [ ] PASS이면 `agent-ops/skills/common/code-review/templates/complete-log-template.md` 기준으로 `complete.log`를 작성하고 active `.md` 파일을 남기지 않는다. +- [ ] PASS이면 active task 디렉터리 `agent-task/{task_name}/`를 `agent-task/archive/YYYY/MM/{task_name}/`로 이동하고 최종 archive 경로에서 이 체크리스트를 갱신한다. +- [ ] PASS split 작업이면 이동 후 빈 active parent `agent-task/jenkins_compatibility_boundary/`를 제거하거나, 남은 sibling/file이 있어 유지했다고 확인한다. +- [ ] WARN/FAIL이면 다음 active `PLAN-{build_lane}-GNN.md`와 `CODE_REVIEW-{review_lane}-GNN.md`를 작성하고 `complete.log`를 작성하지 않는다. + +## 계획 대비 변경 사항 + +_구현 에이전트가 계획과 다르게 구현한 부분을 이유와 함께 기록한다._ + +## 주요 설계 결정 + +_구현 에이전트가 주요 설계 결정 사항을 기록한다._ + +## 리뷰어를 위한 체크포인트 + +- Jenkins env collection이 `DataComposerJenkins.compose()`와 분리됐지만 Jenkins mode 동작은 유지되는가. +- Unix Jenkins variables 로그가 빈 문자열이 아니라 실제 raw JSON을 기록하는가. +- `Application.current`가 Jenkins env를 직접 읽지 않고, build 기본 workspace는 `commonData.workspace`를 우선하는가. +- 기존 `FileData.jenkinsMap` 참조가 외부 호환 alias로 남아 있는가. + +## 검증 결과 + +_구현 에이전트가 각 중간 검증 및 최종 검증 명령 실행 후 출력을 여기에 붙여 넣는다._ + +필수 규칙: +- 검증 명령은 고정된 계약이다. 임의로 대체하지 않는다. +- 대체가 필요하면 `계획 대비 변경 사항`에 이유와 대체 명령을 기록한다. +- `검증 결과`에는 실제 stdout/stderr를 붙여 넣는다. + +### REFACTOR-1 중간 검증 +```bash +$ dart test test/oto_system_runtime_test.dart +(output) +``` + +### REFACTOR-2 중간 검증 +```bash +$ dart test test/oto_application_test.dart test/oto_system_runtime_test.dart +(output) +``` + +### 최종 검증 +```bash +$ dart analyze +(output) +``` + +```bash +$ dart test +(output) +``` + +--- + +> **[IMPLEMENTING AGENT — BEFORE SAVING] Have you filled in every implementation-owned section: completion table, implementation checklist, changes from plan, design decisions, and verification output?** +> If anything is blank, go back and fill it in before saving this file. +> Leave review-agent-only sections unchanged. + +Sections and their ownership: + +| Section | Owner | Note | +|---------|-------|------| +| Header comment, 개요, 리뷰 에이전트 지시 | Fixed at stub creation | Implementing agent must not modify or execute these | +| 구현 항목별 완료 여부 (item names) | Fixed at stub creation | Implementing agent checks `[ ]` -> `[x]` only | +| 구현 체크리스트 (item text/order) | Fixed at stub creation from plan | Implementing agent checks `[ ]` -> `[x]` only | +| 코드리뷰 전용 체크리스트 | Review agent only | Implementing agent must not modify or check this section | +| 계획 대비 변경 사항, 주요 설계 결정 | Implementing agent | Replace placeholder text with actual content | +| 리뷰어를 위한 체크포인트 | Fixed at stub creation | Pre-filled from plan | +| 검증 결과 (section headings + commands) | Fixed at stub creation | Implementing agent fills in command output only | +| 코드리뷰 결과 | Review agent appends | Not included in stub | diff --git a/agent-task/jenkins_compatibility_boundary/01_core_adapter/PLAN-cloud-G07.md b/agent-task/jenkins_compatibility_boundary/01_core_adapter/PLAN-cloud-G07.md new file mode 100644 index 0000000..9ed21b1 --- /dev/null +++ b/agent-task/jenkins_compatibility_boundary/01_core_adapter/PLAN-cloud-G07.md @@ -0,0 +1,284 @@ + + +# Jenkins Core Adapter Boundary - REFACTOR + +## 이 파일을 읽는 구현 에이전트에게 + +구현 후 `CODE_REVIEW-cloud-G07.md`의 구현 에이전트 소유 섹션을 반드시 채운다. 검증 명령을 실제로 실행하고 출력 원문을 붙이며, active 파일은 그대로 둔 채 review 준비 상태를 보고한다. `complete.log` 작성, `.log` 아카이브, task 디렉터리 이동은 code-review-skill 전용이다. + +## 배경 + +활성 Milestone은 Jenkins 실행 경로를 유지하되 장기 제어면이 Jenkins 전용 환경 변수에 묶이지 않게 하는 것이다. 현재 core에는 Jenkins 환경 수집, YAML 추출, 기본 workspace 계산, file/scheduler용 기본 `DataCommon`이 섞여 있다. 이 하위 작업은 Jenkins 호환 adapter를 분리하고 일반 실행 경로의 기본값을 Jenkins 이름에서 걷어내는 foundation이다. + +## 분석 결과 + +### 읽은 파일 + +- `agent-ops/rules/project/rules.md` +- `agent-ops/rules/project/domain/core/rules.md` +- `agent-ops/rules/project/domain/command/rules.md` +- `agent-ops/roadmap/current.md` +- `agent-ops/roadmap/milestones/jenkins-compatibility-boundary.md` +- `lib/oto/application.dart` +- `lib/oto/core/data_composer.dart` +- `lib/oto/core/defined_data.dart` +- `lib/oto/core/system_runtime.dart` +- `lib/oto/core/tag_system.dart` +- `lib/oto/data/base_data.dart` +- `lib/oto/data/command_data.dart` +- `lib/oto/commands/command.dart` +- `test/oto_application_test.dart` +- `test/oto_system_runtime_test.dart` +- `pubspec.yaml` +- `analysis_options.yaml` + +### 테스트 커버리지 공백 + +- Jenkins env 수집: `test/oto_system_runtime_test.dart:160`이 Linux happy path만 검증한다. env 수집 책임이 `DataComposerJenkins.compose()`에서 분리됐는지, Unix 로그 입력이 비어 있지 않은지 검증이 없다. +- 기본 workspace: `test/oto_application_test.dart:41`은 `property.workspace`가 있는 file build만 검증한다. `property.workspace`가 없을 때 Jenkins env 없이 local workspace로 채워지는 회귀 테스트가 없다. +- scheduler common data: scheduler build 경로가 `FileData.jenkinsMap` 이름에 기대는지 여부를 직접 검증하지 않는다. 이 검증은 후속 `02+01_file_scheduler_modes`에서 보강한다. + +### 심볼 참조 + +- 이름을 제거하거나 rename하지 않는다. +- `DataComposerJenkins` 참조: `lib/oto/application.dart:47`, `test/oto_system_runtime_test.dart:186`. +- `Application.current` 참조: `lib/oto/application.dart:29`, `lib/oto/core/tag_system.dart:198`, `lib/oto/core/tag_system.dart:202`. +- `FileData.jenkinsMap` 참조: `lib/oto/application.dart:93`, `lib/oto/core/data_composer.dart:33`, `lib/oto/core/defined_data.dart:56`. + +### 분할 판단 + +분할 정책을 먼저 평가했다. 이 작업은 core adapter 변경, file/scheduler 검증, 문서/샘플 갱신으로 소유 경계와 검증 전략이 다르므로 multi-plan으로 분리한다. + +- 공유 task group: `jenkins_compatibility_boundary` +- `01_core_adapter`: Jenkins env 수집과 기본 workspace foundation. 선행 작업 없음. +- `02+01_file_scheduler_modes`: file/scheduler 실행 검증. `01_core_adapter`의 `complete.log` 이후 진행. +- `03+01,02_docs_samples`: README와 샘플 정리. `01_core_adapter`, `02+01_file_scheduler_modes`의 `complete.log` 이후 진행. + +### 범위 결정 근거 + +- Jenkins mode 제거, `BuildType` enum 제거, Jenkins command 제거는 Milestone 범위 제외라 하지 않는다. +- `lib/oto/data/*.g.dart`는 데이터 모델 필드 변경이 없으므로 수정하지 않는다. +- command/pipeline 실행 로직은 Jenkins env 수집 경계 밖이므로 수정하지 않는다. +- `agent-task/archive/**`는 읽거나 수정하지 않는다. + +### 빌드 등급 + +- build=`cloud-G07`, review=`cloud-G07`: Jenkins env shell/stdout 파싱과 CLI 실행 기본값에 닿는 terminal-agent 성격의 core 변경이다. + +## 구현 체크리스트 + +- [ ] REFACTOR-1 Jenkins 환경 변수 수집 책임을 `DataComposerJenkins.compose()` 밖의 명시적 adapter로 분리한다. +- [ ] REFACTOR-2 file/scheduler/test 모드가 Jenkins 이름의 기본 데이터와 `Platform.environment['WORKSPACE']!`에 직접 기대지 않도록 기본 workspace 경계를 정리한다. +- [ ] 모든 중간 검증과 최종 검증을 실행하고 실제 stdout/stderr를 `CODE_REVIEW-cloud-G07.md`에 기록한다. +- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다. + +## REFACTOR Items + +### REFACTOR-1 Jenkins Env Adapter 분리 + +#### 문제 + +`lib/oto/core/data_composer.dart:39`부터 `DataComposerJenkins.compose()`가 OS 감지, Jenkins env JSON 생성, BuildData 추출, `DataCommon` 생성, 로그 출력을 모두 수행한다. `lib/oto/core/data_composer.dart:96-99`는 Unix 경로에서 `jsonStr`이 계속 빈 문자열이라 Jenkins variables 로그가 실제 수집값을 보여주지 않는다. + +Before (`lib/oto/core/data_composer.dart:39`): + +```dart +class DataComposerJenkins extends DataComposer { + final SystemRuntime runtime; + + DataComposerJenkins({required this.runtime}); + + @override + Future compose(String? yaml, Future Function(String, Color?) printer) async { + Map? jenkinsMap; + String os = Platform.operatingSystem; + var enable = true; + Application.log('Current OS: $os'); + Application.log('Start build...'); + String jsonStr = ''; + if (runtime.isMacOS || runtime.isLinux) { +``` + +#### 해결 방법 + +`data_composer.dart` 안에 public adapter를 추가한다. 새 파일보다 기존 core 파일 안의 작은 타입으로 둔다. + +After: + +```dart +class JenkinsEnvironmentSnapshot { + final Map variables; + final String buildYaml; + final String rawVariablesJson; + + const JenkinsEnvironmentSnapshot({ + required this.variables, + required this.buildYaml, + required this.rawVariablesJson, + }); +} + +class JenkinsEnvironmentCollector { + final SystemRuntime runtime; + + JenkinsEnvironmentCollector({required this.runtime}); + + Future collect( + Future Function(String, Color?) printer) async { + if (runtime.isMacOS || runtime.isLinux) { + return _collectUnix(); + } + if (runtime.isWindows) { + return _collectWindows(); + } + await printer('is not Mac/Windows/Linux. build must be execute in Mac/Windows os system', Color.redStrong); + return null; + } +} +``` + +`DataComposerJenkins.compose()`는 `JenkinsEnvironmentCollector.collect()` 결과를 받아 `commonData`, `buildYaml`, 로그만 설정한다. Windows `getBuildData()`는 collector 내부 helper로 이동하되 기존 동작과 `%PARAM%` 치환을 유지한다. + +#### 수정 파일 및 체크리스트 + +- [ ] `lib/oto/core/data_composer.dart`: `JenkinsEnvironmentSnapshot`, `JenkinsEnvironmentCollector` 추가. +- [ ] `lib/oto/core/data_composer.dart`: `DataComposerJenkins.compose()`를 collector 위임 구조로 축소. +- [ ] `lib/oto/core/data_composer.dart`: Unix 경로에서 실제 raw JSON을 로그에 남기도록 `rawVariablesJson` 사용. +- [ ] `test/oto_system_runtime_test.dart`: collector 또는 composer delegation 테스트를 추가/갱신. + +#### 테스트 작성 + +작성한다. + +- `test/oto_system_runtime_test.dart`: `JenkinsEnvironmentCollector collects linux env and build yaml from runtime` +- 검증 목표: fake runtime의 `runShell` stdout JSON과 `startShell` stdout YAML이 snapshot과 composer 결과로 보존된다. +- 기존 `DataComposerJenkins composes linux env and BuildData from runtime stdout`는 유지하되 adapter 분리 후에도 `commonData.workspace == '/workspace'`, `buildYaml == buildYaml`, `fake.startShellCalls.single.printStdout == false`를 검증한다. + +#### 중간 검증 + +```bash +dart test test/oto_system_runtime_test.dart +``` + +예상 결과: `All tests passed!` + +### REFACTOR-2 Mode-neutral Default Workspace 정리 + +#### 문제 + +`lib/oto/application.dart:29-34`의 `Application.current`가 build type이 Jenkins면 `Platform.environment['WORKSPACE']!`를 직접 읽는다. 이 값은 `SystemRuntime` 주입을 우회하고, property가 없는 Jenkins build에서 hard dependency를 만든다. `lib/oto/application.dart:92-94`와 `lib/oto/core/data_composer.dart:30-36`은 scheduler/file 모드 기본 `DataCommon`을 `FileData.jenkinsMap` 이름으로 가져와 경계가 모호하다. + +Before (`lib/oto/application.dart:29`): + +```dart +static String get current { + if (Application.instance.buildType == BuildType.jenkins) { + return Platform.environment['WORKSPACE']!; + } else { + return path.current; + } +} +``` + +Before (`lib/oto/core/defined_data.dart:3`): + +```dart +class FileData { + static Map? get jenkinsMap { + return { + "workspace": Directory.current.path.replaceAll('\\', '/'), +``` + +#### 해결 방법 + +Jenkins env에서 온 workspace는 `commonData.workspace`에만 머물게 하고, global current는 local path를 의미하게 한다. neutral 기본 데이터 API를 추가하고 기존 `FileData.jenkinsMap`은 compatibility alias로 남긴다. + +After: + +```dart +static String get current => path.current; + +String get defaultWorkspace { + final data = commonData; + if (data != null && data.workspace.isNotEmpty) { + return data.workspace; + } + return current; +} +``` + +```dart +class LocalData { + static Map commonMap({String? workspace}) { + return { + 'workspace': (workspace ?? Directory.current.path).replaceAll('\\', '/'), + 'jenkinsHome': '', + // keep DataCommon compatibility fields + }; + } +} + +class FileData { + static Map? get jenkinsMap => LocalData.commonMap(); +} +``` + +`DataComposerFile`와 scheduler branch는 `LocalData.commonMap()`을 사용한다. `FileData.jenkinsMap`은 기존 테스트나 외부 import를 깨지 않도록 남긴다. + +#### 수정 파일 및 체크리스트 + +- [ ] `lib/oto/application.dart`: `Application.current`에서 Jenkins env 직접 참조 제거. +- [ ] `lib/oto/application.dart`: `property['workspace']` 기본값을 `defaultWorkspace`에서 채운다. +- [ ] `lib/oto/core/defined_data.dart`: neutral `LocalData.commonMap()` 추가, 기존 `FileData.jenkinsMap`은 alias 유지. +- [ ] `lib/oto/core/data_composer.dart`: `DataComposerFile`이 `LocalData.commonMap()`을 사용. +- [ ] `lib/oto/application.dart`: `BuildType.scheduler` branch가 `LocalData.commonMap()`을 사용. +- [ ] `test/oto_application_test.dart`: workspace 없는 file build 회귀 테스트 추가. + +#### 테스트 작성 + +작성한다. + +- `test/oto_application_test.dart`: `file build without property workspace uses local workspace without Jenkins env` +- 검증 목표: `BuildType.file` YAML에 `property.workspace`가 없어도 build가 성공하고 `Application.instance.property['workspace']`가 `Directory.current.path`와 일치한다. + +#### 중간 검증 + +```bash +dart test test/oto_application_test.dart test/oto_system_runtime_test.dart +``` + +예상 결과: `All tests passed!` + +## 의존 관계 및 구현 순서 + +1. `REFACTOR-1`을 먼저 적용해 Jenkins env 수집 책임을 분리한다. +2. `REFACTOR-2`를 적용해 non-Jenkins 기본값을 neutral API로 이동한다. +3. 중간 검증 후 최종 검증을 실행한다. + +## 수정 파일 요약 + +| 파일 | 항목 | +|------|------| +| `lib/oto/core/data_composer.dart` | REFACTOR-1, REFACTOR-2 | +| `lib/oto/core/defined_data.dart` | REFACTOR-2 | +| `lib/oto/application.dart` | REFACTOR-2 | +| `test/oto_system_runtime_test.dart` | REFACTOR-1 | +| `test/oto_application_test.dart` | REFACTOR-2 | + +## 최종 검증 + +```bash +dart analyze +``` + +예상 결과: `No issues found!` + +```bash +dart test +``` + +예상 결과: `All tests passed!` + +검증 명령은 이 저장소에서 실행 확인했다. 테스트 캐시 개념이 없는 Dart test라 별도 cache busting은 필요 없다. + +모든 코드 변경 완료 후 반드시 `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 채운다. 이 파일 작성이 구현의 마지막 단계다. diff --git a/agent-task/jenkins_compatibility_boundary/02+01_file_scheduler_modes/CODE_REVIEW-cloud-G07.md b/agent-task/jenkins_compatibility_boundary/02+01_file_scheduler_modes/CODE_REVIEW-cloud-G07.md new file mode 100644 index 0000000..0bff387 --- /dev/null +++ b/agent-task/jenkins_compatibility_boundary/02+01_file_scheduler_modes/CODE_REVIEW-cloud-G07.md @@ -0,0 +1,123 @@ + + +# Code Review Reference - REFACTOR + +> **[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. +> Finalization (`코드리뷰 결과`, log rename, `complete.log`, archive moves, `코드리뷰 전용 체크리스트`) is review-agent-only, even after compaction/resume. +> Follow the ownership table at the bottom of this file for which sections you own. + +## 개요 + +date=2026-05-22 +task=jenkins_compatibility_boundary/02+01_file_scheduler_modes, plan=0, tag=REFACTOR + +## 이 파일을 읽는 리뷰 에이전트에게 + +> **[REVIEW AGENT ONLY]** 아래 종결 절차는 코드리뷰 에이전트 전용이다. 구현 에이전트는 이 섹션을 실행하지 않는다. + +각 항목의 구현을 실제 소스 파일과 대조하고, `검증 결과` 섹션의 출력이 코드와 일치하는지 확인하세요. +리뷰 완료는 아래 순서까지 끝난 상태를 의미합니다. + +1. 판정을 append한다. +2. `CODE_REVIEW-cloud-G07.md` -> `code_review_cloud_G07_0.log`, `PLAN-cloud-G07.md` -> `plan_cloud_G07_0.log`로 아카이브한다. +3. PASS이면 `complete.log` 작성 후 active `.md` 파일을 남기지 않는다. +4. PASS이면 active task 디렉터리 `agent-task/jenkins_compatibility_boundary/02+01_file_scheduler_modes/`를 archive로 이동한다. + +--- + +## 구현 항목별 완료 여부 + +| 항목 | 완료 여부 | +|------|---------| +| [REFACTOR-1] file mode Jenkins-free regression | [ ] | +| [REFACTOR-2] scheduler mode Jenkins-free regression | [ ] | + +## 구현 체크리스트 + +- [ ] REFACTOR-1 file mode가 Jenkins env 없이 기본 workspace를 채우고 실행되는 regression test를 추가한다. +- [ ] REFACTOR-2 scheduler mode가 Jenkins env 없이 `DataBuild`와 log path만으로 실행되는 regression test를 추가한다. +- [ ] 모든 중간 검증과 최종 검증을 실행하고 실제 stdout/stderr를 `CODE_REVIEW-cloud-G07.md`에 기록한다. +- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다. + +## 코드리뷰 전용 체크리스트 + +> **[REVIEW AGENT ONLY]** 이 체크리스트는 코드리뷰 에이전트만 사용한다. +> 구현 에이전트는 이 섹션을 수정하거나 체크하지 않는다. + +- [ ] `코드리뷰 결과`에 `PASS`, `WARN`, `FAIL` 중 하나의 판정을 append한다. +- [ ] 판정과 `차원별 평가`, Required/Suggested/Nit 분류가 서로 일치한다. +- [ ] active `CODE_REVIEW-*-G??.md`를 `code_review_{review_lane}_GNN_N.log`로 아카이브한다. +- [ ] active `PLAN-*-G??.md`를 `plan_{build_lane}_GNN_M.log`로 아카이브한다. +- [ ] PASS이면 `complete.log`를 작성하고 active `.md` 파일을 남기지 않는다. +- [ ] PASS이면 active task 디렉터리를 archive로 이동하고 최종 archive 경로에서 이 체크리스트를 갱신한다. +- [ ] PASS split 작업이면 이동 후 빈 active parent `agent-task/jenkins_compatibility_boundary/`를 제거하거나, 남은 sibling/file이 있어 유지했다고 확인한다. +- [ ] WARN/FAIL이면 다음 active `PLAN-{build_lane}-GNN.md`와 `CODE_REVIEW-{review_lane}-GNN.md`를 작성하고 `complete.log`를 작성하지 않는다. + +## 계획 대비 변경 사항 + +_구현 에이전트가 계획과 다르게 구현한 부분을 이유와 함께 기록한다._ + +## 주요 설계 결정 + +_구현 에이전트가 주요 설계 결정 사항을 기록한다._ + +## 리뷰어를 위한 체크포인트 + +- `02+01_file_scheduler_modes`가 `01_core_adapter` 완료 후 진행됐는가. +- file mode test가 `property.workspace` 없는 YAML을 사용해 Jenkins env 없는 default workspace를 검증하는가. +- scheduler mode test가 daemon process가 아니라 `BuildType.scheduler` execution contract를 검증하는가. +- temp files/logs cleanup이 안정적인가. + +## 검증 결과 + +_구현 에이전트가 각 중간 검증 및 최종 검증 명령 실행 후 출력을 여기에 붙여 넣는다._ + +필수 규칙: +- 검증 명령은 고정된 계약이다. 임의로 대체하지 않는다. +- 대체가 필요하면 `계획 대비 변경 사항`에 이유와 대체 명령을 기록한다. +- `검증 결과`에는 실제 stdout/stderr를 붙여 넣는다. + +### REFACTOR-1 중간 검증 +```bash +$ dart test test/oto_application_test.dart +(output) +``` + +### REFACTOR-2 중간 검증 +```bash +$ dart test test/oto_application_test.dart test/oto_scheduler_runtime_test.dart +(output) +``` + +### 최종 검증 +```bash +$ dart analyze +(output) +``` + +```bash +$ dart test +(output) +``` + +--- + +> **[IMPLEMENTING AGENT — BEFORE SAVING] Have you filled in every implementation-owned section: completion table, implementation checklist, changes from plan, design decisions, and verification output?** +> If anything is blank, go back and fill it in before saving this file. +> Leave review-agent-only sections unchanged. + +Sections and their ownership: + +| Section | Owner | Note | +|---------|-------|------| +| Header comment, 개요, 리뷰 에이전트 지시 | Fixed at stub creation | Implementing agent must not modify or execute these | +| 구현 항목별 완료 여부 (item names) | Fixed at stub creation | Implementing agent checks `[ ]` -> `[x]` only | +| 구현 체크리스트 (item text/order) | Fixed at stub creation from plan | Implementing agent checks `[ ]` -> `[x]` only | +| 코드리뷰 전용 체크리스트 | Review agent only | Implementing agent must not modify or check this section | +| 계획 대비 변경 사항, 주요 설계 결정 | Implementing agent | Replace placeholder text with actual content | +| 리뷰어를 위한 체크포인트 | Fixed at stub creation | Pre-filled from plan | +| 검증 결과 (section headings + commands) | Fixed at stub creation | Implementing agent fills in command output only | +| 코드리뷰 결과 | Review agent appends | Not included in stub | diff --git a/agent-task/jenkins_compatibility_boundary/02+01_file_scheduler_modes/PLAN-cloud-G07.md b/agent-task/jenkins_compatibility_boundary/02+01_file_scheduler_modes/PLAN-cloud-G07.md new file mode 100644 index 0000000..116701d --- /dev/null +++ b/agent-task/jenkins_compatibility_boundary/02+01_file_scheduler_modes/PLAN-cloud-G07.md @@ -0,0 +1,239 @@ + + +# File And Scheduler Jenkins-free Verification - REFACTOR + +## 이 파일을 읽는 구현 에이전트에게 + +구현 후 `CODE_REVIEW-cloud-G07.md`의 구현 에이전트 소유 섹션을 반드시 채운다. 검증 명령을 실제로 실행하고 출력 원문을 붙이며, active 파일은 그대로 둔 채 review 준비 상태를 보고한다. `complete.log` 작성, `.log` 아카이브, task 디렉터리 이동은 code-review-skill 전용이다. + +## 배경 + +Milestone의 필수 기능은 file 모드와 scheduler 모드가 Jenkins 없이 실행 가능한 경로로 검증되어 있는 것이다. core foundation은 `01_core_adapter`에서 정리하므로, 이 하위 작업은 production 동작을 넓히기보다 회귀 테스트와 bin-level smoke 계약을 추가한다. + +## 분석 결과 + +### 읽은 파일 + +- `agent-ops/rules/project/domain/cli/rules.md` +- `agent-ops/rules/project/domain/scheduler/rules.md` +- `agent-ops/rules/project/domain/core/rules.md` +- `agent-ops/roadmap/milestones/jenkins-compatibility-boundary.md` +- `lib/cli/commands/command_exe.dart` +- `lib/cli/commands/command_scheduler.dart` +- `lib/cli/commands/scheduler/scheduler_isolate.dart` +- `lib/cli/commands/scheduler/scheduler_interval.dart` +- `lib/cli/commands/scheduler/scheduler_manager.dart` +- `lib/oto/application.dart` +- `lib/oto/data/command_data.dart` +- `test/oto_application_test.dart` +- `test/oto_scheduler_runtime_test.dart` +- `test/oto_system_runtime_test.dart` +- `assets/yaml/sample/12_scheduler.yaml` + +### 테스트 커버리지 공백 + +- file mode: `test/oto_application_test.dart:41` covers a print-only file build with explicit `property.workspace`; it does not assert Jenkins-free default workspace when `property` is absent. +- CLI file smoke: `test/oto_application_test.dart:656` covers actual `dart run bin/main.dart exe -f --json`; it can remain the bin-level file smoke. +- scheduler mode: `test/oto_scheduler_runtime_test.dart:151` covers process launch/routing; it does not exercise `Application.build(BuildType.scheduler, buildData: ..., logPath: ...)`. +- scheduler YAML parse: `test/oto_application_test.dart:435` covers malformed scheduler section; no positive scheduler buildData execution regression exists. + +### 심볼 참조 + +- 이름을 제거하거나 rename하지 않는다. +- `BuildType.scheduler` 참조: `lib/cli/commands/command_exe.dart:201`, `lib/oto/application.dart:92`. +- `CommandExe.executeScheduler` 참조: `lib/cli/commands/scheduler/scheduler_isolate.dart:132`. +- `scheduler.interval` 참조: `lib/cli/commands/scheduler/scheduler_isolate.dart:85`, `lib/cli/commands/scheduler/scheduler_interval.dart:18`. + +### 분할 판단 + +분할 정책을 평가했다. 이 subtask는 `01_core_adapter`의 foundation이 있어야 의미 있는 regression test를 작성할 수 있으므로 `02+01_file_scheduler_modes`로 분리했다. production API 변경 없이 verification 중심 작업이며, docs/sample 정리는 `03+01,02_docs_samples`에 둔다. + +### 범위 결정 근거 + +- scheduler daemon start/terminate 구현은 이미 `test/oto_scheduler_runtime_test.dart`에서 주입 runtime으로 검증되므로 변경하지 않는다. +- OS startup 등록, launchd/Task Scheduler 통합은 실제 외부 시스템 의존이라 이 계획에서 새 integration test를 만들지 않는다. +- command/pipeline 내부 실행 규칙은 scope 밖이다. + +### 빌드 등급 + +- build=`cloud-G07`, review=`cloud-G07`: scheduler와 CLI 실행 경계, bin-level smoke 출력, exit-status 계약을 검증하는 terminal-agent 성격의 작업이다. + +## 구현 체크리스트 + +- [ ] REFACTOR-1 file mode가 Jenkins env 없이 기본 workspace를 채우고 실행되는 regression test를 추가한다. +- [ ] REFACTOR-2 scheduler mode가 Jenkins env 없이 `DataBuild`와 log path만으로 실행되는 regression test를 추가한다. +- [ ] 모든 중간 검증과 최종 검증을 실행하고 실제 stdout/stderr를 `CODE_REVIEW-cloud-G07.md`에 기록한다. +- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다. + +## REFACTOR Items + +### REFACTOR-1 File Mode Jenkins-free Regression + +#### 문제 + +`lib/cli/commands/command_exe.dart:99-104`는 file mode에서 YAML 파일을 읽어 `Application.build(BuildType.file)`로 넘긴다. 하지만 기존 positive tests는 YAML에 `property.workspace`가 있는 경우만 다루며, Jenkins env 없는 기본 workspace 경계를 직접 고정하지 않는다. + +Before (`test/oto_application_test.dart:41`): + +```dart +test('file build returns success for print-only pipeline', () async { + const yaml = ''' +property: + workspace: . +commands: +``` + +#### 해결 방법 + +`test/oto_application_test.dart`에 `property` 섹션이 없는 file build 테스트를 추가한다. 실행 후 `Application.instance.property['workspace']`가 local current path로 채워졌는지 확인한다. + +After: + +```dart +test('file build without property workspace uses local workspace without Jenkins env', () async { + const yaml = ''' +commands: + - command: Print + id: hello + param: + message: hi +pipeline: + id: main + workflow: + - exe: hello +'''; + + final result = await Application.instance.build( + BuildType.file, + yamlContent: yaml, + logEnable: false, + ); + + expect(result.success, isTrue); + expect(Application.instance.property['workspace'], Directory.current.path); +}); +``` + +#### 수정 파일 및 체크리스트 + +- [ ] `test/oto_application_test.dart`: file mode no-property workspace regression 추가. +- [ ] production source는 `01_core_adapter` 이후 실패가 드러날 때만 계획 대비 변경 사항에 기록하고 최소 수정한다. + +#### 테스트 작성 + +작성한다. + +- `test/oto_application_test.dart`: 위 regression test. +- fixture는 inline YAML만 사용한다. + +#### 중간 검증 + +```bash +dart test test/oto_application_test.dart +``` + +예상 결과: `All tests passed!` + +### REFACTOR-2 Scheduler Mode Jenkins-free Regression + +#### 문제 + +`lib/cli/commands/scheduler/scheduler_isolate.dart:124-132`는 scheduler tick에서 `CommandExe.executeScheduler(data, logEnable, logFile.path)`를 호출하고, `lib/cli/commands/command_exe.dart:199-203`은 `BuildType.scheduler` isolate를 만든다. 그러나 현재 테스트는 scheduler process control에 집중되어 있어 `Application.build(BuildType.scheduler, buildData: ..., logPath: ...)`가 Jenkins env 없이 실제 pipeline을 실행하는지 검증하지 않는다. + +Before (`lib/oto/application.dart:92`): + +```dart +if (_buildType == BuildType.scheduler) { + commonData = DataCommon.fromJson(FileData.jenkinsMap!); + build = buildData!; + _logFile = File(logPath!); + CLI.logFunc = log; +} +``` + +#### 해결 방법 + +`test/oto_application_test.dart`에 scheduler `DataBuild` positive regression을 추가한다. `Application.getMapFromYamlA()`와 `DataBuild.fromJson()`으로 scheduler YAML을 만들고, temp log path를 넘겨 `BuildType.scheduler`를 실행한다. + +After: + +```dart +test('scheduler build data runs without Jenkins env', () async { + final logFile = File('${Directory.systemTemp.path}/oto_scheduler_${DateTime.now().microsecondsSinceEpoch}.log'); + const yaml = ''' +scheduler: + alias: local-test + interval: 1000 + enableLog: true +commands: + - command: Print + id: hello + param: + message: hi +pipeline: + id: main + workflow: + - exe: hello +'''; + final build = DataBuild.fromJson(Application.getMapFromYamlA(yaml)!); + + final result = await Application.instance.build( + BuildType.scheduler, + buildData: build, + logEnable: false, + logPath: logFile.path, + ); + + expect(result.success, isTrue); +}); +``` + +#### 수정 파일 및 체크리스트 + +- [ ] `test/oto_application_test.dart`: scheduler mode no-Jenkins regression 추가. +- [ ] test cleanup에서 temp log file을 삭제한다. +- [ ] `test/oto_scheduler_runtime_test.dart`는 process control 변경이 필요할 때만 수정한다. + +#### 테스트 작성 + +작성한다. + +- `test/oto_application_test.dart`: `scheduler build data runs without Jenkins env` +- assertion: `result.success == true`, `exitCode == 0`, temp log handling이 예외를 내지 않음. + +#### 중간 검증 + +```bash +dart test test/oto_application_test.dart test/oto_scheduler_runtime_test.dart +``` + +예상 결과: `All tests passed!` + +## 의존 관계 및 구현 순서 + +이 subtask는 sibling `01_core_adapter`의 `complete.log`가 있어야 시작한다. directory name `02+01_file_scheduler_modes`의 `+01`이 유일한 runtime dependency다. + +## 수정 파일 요약 + +| 파일 | 항목 | +|------|------| +| `test/oto_application_test.dart` | REFACTOR-1, REFACTOR-2 | +| `test/oto_scheduler_runtime_test.dart` | REFACTOR-2, 필요 시 | + +## 최종 검증 + +```bash +dart analyze +``` + +예상 결과: `No issues found!` + +```bash +dart test +``` + +예상 결과: `All tests passed!` + +검증 명령은 이 저장소에서 실행 확인했다. 테스트 캐시 개념이 없는 Dart test라 별도 cache busting은 필요 없다. + +모든 코드 변경 완료 후 반드시 `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 채운다. 이 파일 작성이 구현의 마지막 단계다. diff --git a/agent-task/jenkins_compatibility_boundary/03+01,02_docs_samples/CODE_REVIEW-local-G04.md b/agent-task/jenkins_compatibility_boundary/03+01,02_docs_samples/CODE_REVIEW-local-G04.md new file mode 100644 index 0000000..52f13f9 --- /dev/null +++ b/agent-task/jenkins_compatibility_boundary/03+01,02_docs_samples/CODE_REVIEW-local-G04.md @@ -0,0 +1,136 @@ + + +# Code Review Reference - REFACTOR + +> **[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. +> Finalization (`코드리뷰 결과`, log rename, `complete.log`, archive moves, `코드리뷰 전용 체크리스트`) is review-agent-only, even after compaction/resume. +> Follow the ownership table at the bottom of this file for which sections you own. + +## 개요 + +date=2026-05-22 +task=jenkins_compatibility_boundary/03+01,02_docs_samples, plan=0, tag=REFACTOR + +## 이 파일을 읽는 리뷰 에이전트에게 + +> **[REVIEW AGENT ONLY]** 아래 종결 절차는 코드리뷰 에이전트 전용이다. 구현 에이전트는 이 섹션을 실행하지 않는다. + +각 항목의 구현을 실제 소스 파일과 대조하고, `검증 결과` 섹션의 출력이 코드와 일치하는지 확인하세요. +리뷰 완료는 아래 순서까지 끝난 상태를 의미합니다. + +1. 판정을 append한다. +2. `CODE_REVIEW-local-G04.md` -> `code_review_local_G04_0.log`, `PLAN-local-G04.md` -> `plan_local_G04_0.log`로 아카이브한다. +3. PASS이면 `complete.log` 작성 후 active `.md` 파일을 남기지 않는다. +4. PASS이면 active task 디렉터리 `agent-task/jenkins_compatibility_boundary/03+01,02_docs_samples/`를 archive로 이동한다. + +--- + +## 구현 항목별 완료 여부 + +| 항목 | 완료 여부 | +|------|---------| +| [REFACTOR-1] README 실행 경계 명시 | [ ] | +| [REFACTOR-2] Scheduler/Jenkins sample 주석 정리 | [ ] | +| [REFACTOR-3] README stale field 회귀 방지 | [ ] | + +## 구현 체크리스트 + +- [ ] REFACTOR-1 README에서 Jenkins mode, file mode, scheduler mode의 책임 경계를 명확히 한다. +- [ ] REFACTOR-2 scheduler/Jenkins 샘플 주석을 Jenkins-free 실행 경계와 실제 interval 단위에 맞게 정리한다. +- [ ] REFACTOR-3 README 예제 stale field를 고치고 최소 문서 회귀 테스트를 추가한다. +- [ ] 모든 중간 검증과 최종 검증을 실행하고 실제 stdout/stderr를 `CODE_REVIEW-local-G04.md`에 기록한다. +- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다. + +## 코드리뷰 전용 체크리스트 + +> **[REVIEW AGENT ONLY]** 이 체크리스트는 코드리뷰 에이전트만 사용한다. +> 구현 에이전트는 이 섹션을 수정하거나 체크하지 않는다. + +- [ ] `코드리뷰 결과`에 `PASS`, `WARN`, `FAIL` 중 하나의 판정을 append한다. +- [ ] 판정과 `차원별 평가`, Required/Suggested/Nit 분류가 서로 일치한다. +- [ ] active `CODE_REVIEW-*-G??.md`를 `code_review_{review_lane}_GNN_N.log`로 아카이브한다. +- [ ] active `PLAN-*-G??.md`를 `plan_{build_lane}_GNN_M.log`로 아카이브한다. +- [ ] PASS이면 `complete.log`를 작성하고 active `.md` 파일을 남기지 않는다. +- [ ] PASS이면 active task 디렉터리를 archive로 이동하고 최종 archive 경로에서 이 체크리스트를 갱신한다. +- [ ] PASS split 작업이면 이동 후 빈 active parent `agent-task/jenkins_compatibility_boundary/`를 제거하거나, 남은 sibling/file이 있어 유지했다고 확인한다. +- [ ] WARN/FAIL이면 다음 active `PLAN-{build_lane}-GNN.md`와 `CODE_REVIEW-{review_lane}-GNN.md`를 작성하고 `complete.log`를 작성하지 않는다. + +## 계획 대비 변경 사항 + +_구현 에이전트가 계획과 다르게 구현한 부분을 이유와 함께 기록한다._ + +## 주요 설계 결정 + +_구현 에이전트가 주요 설계 결정 사항을 기록한다._ + +## 리뷰어를 위한 체크포인트 + +- README가 `oto -j`, `oto -f`, `oto scheduler`의 Jenkins env 요구 여부를 명확히 구분하는가. +- scheduler interval 단위가 code(`Duration(milliseconds: interval)`)와 README/sample에서 일치하는가. +- `JenkinsParameterModify` sample이 Jenkins execution mode와 혼동되지 않는가. +- README stale `workspacePath` 회귀 테스트가 comment line을 제외하고 검사하는가. + +## 검증 결과 + +_구현 에이전트가 각 중간 검증 및 최종 검증 명령 실행 후 출력을 여기에 붙여 넣는다._ + +필수 규칙: +- 검증 명령은 고정된 계약이다. 임의로 대체하지 않는다. +- 대체가 필요하면 `계획 대비 변경 사항`에 이유와 대체 명령을 기록한다. +- `검증 결과`에는 실제 stdout/stderr를 붙여 넣는다. + +### REFACTOR-1 중간 검증 +```bash +$ rg --sort path -n "Jenkins 호환 경계|JenkinsParameterModify|oto -f |oto scheduler" README.md +(output) +``` + +### REFACTOR-2 중간 검증 +```bash +$ dart test test/oto_command_catalog_test.dart +(output) +``` + +### REFACTOR-3 중간 검증 +```bash +$ dart test test/oto_command_catalog_test.dart +(output) +``` + +### 최종 검증 +```bash +$ dart analyze +(output) +``` + +```bash +$ dart test test/oto_command_catalog_test.dart +(output) +``` + +```bash +$ dart test +(output) +``` + +--- + +> **[IMPLEMENTING AGENT — BEFORE SAVING] Have you filled in every implementation-owned section: completion table, implementation checklist, changes from plan, design decisions, and verification output?** +> If anything is blank, go back and fill it in before saving this file. +> Leave review-agent-only sections unchanged. + +Sections and their ownership: + +| Section | Owner | Note | +|---------|-------|------| +| Header comment, 개요, 리뷰 에이전트 지시 | Fixed at stub creation | Implementing agent must not modify or execute these | +| 구현 항목별 완료 여부 (item names) | Fixed at stub creation | Implementing agent checks `[ ]` -> `[x]` only | +| 구현 체크리스트 (item text/order) | Fixed at stub creation from plan | Implementing agent checks `[ ]` -> `[x]` only | +| 코드리뷰 전용 체크리스트 | Review agent only | Implementing agent must not modify or check this section | +| 계획 대비 변경 사항, 주요 설계 결정 | Implementing agent | Replace placeholder text with actual content | +| 리뷰어를 위한 체크포인트 | Fixed at stub creation | Pre-filled from plan | +| 검증 결과 (section headings + commands) | Fixed at stub creation | Implementing agent fills in command output only | +| 코드리뷰 결과 | Review agent appends | Not included in stub | diff --git a/agent-task/jenkins_compatibility_boundary/03+01,02_docs_samples/PLAN-local-G04.md b/agent-task/jenkins_compatibility_boundary/03+01,02_docs_samples/PLAN-local-G04.md new file mode 100644 index 0000000..4abd4d5 --- /dev/null +++ b/agent-task/jenkins_compatibility_boundary/03+01,02_docs_samples/PLAN-local-G04.md @@ -0,0 +1,246 @@ + + +# Jenkins Boundary Docs And Samples - REFACTOR + +## 이 파일을 읽는 구현 에이전트에게 + +구현 후 `CODE_REVIEW-local-G04.md`의 구현 에이전트 소유 섹션을 반드시 채운다. 검증 명령을 실제로 실행하고 출력 원문을 붙이며, active 파일은 그대로 둔 채 review 준비 상태를 보고한다. `complete.log` 작성, `.log` 아카이브, task 디렉터리 이동은 code-review-skill 전용이다. + +## 배경 + +Milestone은 Jenkins 전용 경로와 일반 실행 경로가 문서에서 혼동되지 않아야 한다고 요구한다. README는 이미 CLI 호환 기준선을 말하지만 Jenkins env adapter, file/scheduler 일반 실행, Jenkins command sample의 차이를 더 명시해야 한다. scheduler interval 단위도 README와 샘플 사이에 차이가 있다. + +## 분석 결과 + +### 읽은 파일 + +- `agent-ops/rules/project/domain/sample/rules.md` +- `agent-ops/rules/project/domain/cli/rules.md` +- `agent-ops/rules/project/domain/scheduler/rules.md` +- `agent-ops/roadmap/milestones/jenkins-compatibility-boundary.md` +- `README.md` +- `assets/yaml/sample/01_basic.yaml` +- `assets/yaml/sample/12_scheduler.yaml` +- `assets/yaml/sample/20_jenkins.yaml` +- `lib/cli/commands/scheduler/scheduler_interval.dart` +- `test/oto_command_catalog_test.dart` + +### 테스트 커버리지 공백 + +- sample parse: `test/oto_command_catalog_test.dart:346` verifies samplePath YAML parses as map with commands list. +- README examples: no test guards stale `workspacePath` in README. README currently uses `workspacePath` at `README.md:82`, while iOS samples/tests expect `xcworkspaceFilePath`. +- scheduler interval docs: `assets/yaml/sample/12_scheduler.yaml:10` says milliseconds; `README.md:267` says seconds. No test covers docs text. + +### 심볼 참조 + +- 이름을 제거하거나 rename하지 않는다. +- `workspacePath` non-commented references found in `README.md:82` and `assets/yaml/sample/04_pipeline_exe_handle.yaml:25`. This plan changes README only; sample 04 is outside Jenkins boundary and should be handled separately if stale sample cleanup is requested. + +### 분할 판단 + +분할 정책을 평가했다. docs/sample 작업은 code foundation과 verification이 완료된 뒤 반영하는 편이 안전하므로 `03+01,02_docs_samples`로 분리했다. directory name의 `+01,02`가 dependency source of truth다. + +### 범위 결정 근거 + +- 이 plan은 README와 Jenkins/scheduler samples만 다룬다. +- `assets/yaml/sample/04_pipeline_exe_handle.yaml`의 stale `workspacePath`는 Jenkins boundary와 직접 관련이 없어 제외한다. +- 로드맵 파일과 Milestone 상태는 사용자가 명시하지 않았으므로 수정하지 않는다. + +### 빌드 등급 + +- build=`local-G04`, review=`local-G04`: 문서/샘플 중심이며 sample parse 테스트로 검증 가능한 낮은 blast radius 작업이다. + +## 구현 체크리스트 + +- [ ] REFACTOR-1 README에서 Jenkins mode, file mode, scheduler mode의 책임 경계를 명확히 한다. +- [ ] REFACTOR-2 scheduler/Jenkins 샘플 주석을 Jenkins-free 실행 경계와 실제 interval 단위에 맞게 정리한다. +- [ ] REFACTOR-3 README 예제 stale field를 고치고 최소 문서 회귀 테스트를 추가한다. +- [ ] 모든 중간 검증과 최종 검증을 실행하고 실제 stdout/stderr를 `CODE_REVIEW-local-G04.md`에 기록한다. +- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다. + +## REFACTOR Items + +### REFACTOR-1 README 실행 경계 명시 + +#### 문제 + +`README.md:53-54`는 Jenkins 의존과 file/scheduler 전제를 짧게만 설명한다. Milestone 완료 기준인 “Jenkins 없이도 OTO 파이프라인 실행 경로를 설명”하기에는 adapter/일반 실행 경계가 부족하다. + +Before (`README.md:53`): + +```markdown +Jenkins 의존은 `jenkins` 실행 모드의 호환 경로로 남긴다. +새 자동화 표면은 `file`과 `scheduler` 모드가 Jenkins 환경 변수 없이 동작할 수 있다는 전제를 깨지 않아야 한다. +``` + +#### 해결 방법 + +CLI 호환 기준선 아래에 짧은 `Jenkins 호환 경계` 소절을 추가한다. + +After: + +```markdown +### Jenkins 호환 경계 + +- `oto -j`만 Jenkins 환경 변수와 Jenkins BuildData 입력을 읽는 compatibility adapter다. +- `oto -f `는 YAML 파일만 입력으로 삼으며 Jenkins env 없이 local workspace 기본값으로 실행된다. +- `oto scheduler ...`는 등록된 YAML과 scheduler 설정으로 실행되며 Jenkins env를 요구하지 않는다. +- `JenkinsParameterModify`는 Jenkins job XML을 다루는 command일 뿐 `-j` 실행 모드를 요구한다는 뜻이 아니다. +``` + +#### 수정 파일 및 체크리스트 + +- [ ] `README.md`: CLI 호환 기준선 아래 boundary 소절 추가. +- [ ] `README.md`: Jenkins mode 제거로 읽히는 표현을 쓰지 않는다. + +#### 테스트 작성 + +직접적인 README 렌더 테스트는 생략한다. `REFACTOR-3`에서 stale field 문서 회귀 테스트를 추가한다. + +#### 중간 검증 + +```bash +rg --sort path -n "Jenkins 호환 경계|JenkinsParameterModify|oto -f |oto scheduler" README.md +``` + +예상 결과: 새 boundary 문구가 README에 검색된다. + +### REFACTOR-2 Scheduler/Jenkins Sample 주석 정리 + +#### 문제 + +`assets/yaml/sample/12_scheduler.yaml:10`은 interval이 ms 단위라고 쓰고, 실제 `SchedulerInterval`도 `Duration(milliseconds: interval)`을 사용한다. 반면 `README.md:267`은 초 단위라고 설명한다. `assets/yaml/sample/20_jenkins.yaml:2`는 Jenkins command sample이 Jenkins execution mode sample로 오해될 수 있다. + +Before (`README.md:266`): + +```markdown + cron: "0 2 * * *" # cron 표현식 또는 + # interval: 3600 # 초 단위 interval +``` + +Before (`assets/yaml/sample/20_jenkins.yaml:2`): + +```yaml +# [샘플] Jenkins 파라미터 수정 +``` + +#### 해결 방법 + +README interval 설명을 ms 단위로 맞추고, scheduler/Jenkins 샘플 상단 주석에 Jenkins env 요구 여부를 명시한다. + +After: + +```markdown + cron: "0 2 * * *" # cron 표현식 또는 + # interval: 3600000 # 밀리초 단위 interval +``` + +```yaml +# [샘플] Jenkins 파라미터 수정 command +# Jenkins job XML을 다루는 command 예시이며, oto -j 실행 모드를 요구하지 않는다. +``` + +#### 수정 파일 및 체크리스트 + +- [ ] `README.md`: scheduler interval 단위 문구를 milliseconds로 정정. +- [ ] `assets/yaml/sample/12_scheduler.yaml`: Jenkins env 없이 등록 가능한 scheduler YAML임을 주석으로 명시. +- [ ] `assets/yaml/sample/20_jenkins.yaml`: command sample과 Jenkins execution mode를 구분하는 주석 추가. + +#### 테스트 작성 + +새 테스트는 생략한다. 샘플 YAML parse regression은 기존 `test/oto_command_catalog_test.dart:346`이 담당한다. + +#### 중간 검증 + +```bash +dart test test/oto_command_catalog_test.dart +``` + +예상 결과: `All tests passed!` + +### REFACTOR-3 README stale field 회귀 방지 + +#### 문제 + +`README.md:82`는 `workspacePath`를 사용한다. `test/oto_command_catalog_test.dart:105`는 iOS sample에서 `workspacePath`를 금지하지만 README 예제는 보호하지 않는다. + +Before (`README.md:79`): + +```yaml + - command: BuildiOS + id: buildApp + param: + workspacePath: /ios/Runner.xcworkspace + scheme: Runner +``` + +#### 해결 방법 + +README 예제를 현재 iOS 모델에 맞춰 `xcworkspaceFilePath`로 바꾸고, README의 non-comment YAML 예제에 stale field가 돌아오지 않도록 테스트를 추가한다. + +After: + +```yaml + - command: BuildiOS + id: buildApp + param: + xcworkspaceFilePath: /ios/Runner.xcworkspace + scheme: Runner +``` + +#### 수정 파일 및 체크리스트 + +- [ ] `README.md`: `workspacePath` 예제를 `xcworkspaceFilePath`로 교체. +- [ ] `test/oto_command_catalog_test.dart`: README non-comment line에 `workspacePath:`가 없는지 검증하는 테스트 추가. + +#### 테스트 작성 + +작성한다. + +- `test/oto_command_catalog_test.dart`: `README examples must not contain stale field workspacePath` +- assertion: comment line 제외 후 `RegExp(r'^[ \t]+workspacePath\s*:')`와 매칭되는 줄이 없어야 한다. + +#### 중간 검증 + +```bash +dart test test/oto_command_catalog_test.dart +``` + +예상 결과: `All tests passed!` + +## 의존 관계 및 구현 순서 + +이 subtask는 sibling `01_core_adapter`, `02+01_file_scheduler_modes`의 `complete.log`가 있어야 시작한다. directory name `03+01,02_docs_samples`의 `+01,02`가 유일한 runtime dependency다. + +## 수정 파일 요약 + +| 파일 | 항목 | +|------|------| +| `README.md` | REFACTOR-1, REFACTOR-2, REFACTOR-3 | +| `assets/yaml/sample/12_scheduler.yaml` | REFACTOR-2 | +| `assets/yaml/sample/20_jenkins.yaml` | REFACTOR-2 | +| `test/oto_command_catalog_test.dart` | REFACTOR-3 | + +## 최종 검증 + +```bash +dart analyze +``` + +예상 결과: `No issues found!` + +```bash +dart test test/oto_command_catalog_test.dart +``` + +예상 결과: `All tests passed!` + +```bash +dart test +``` + +예상 결과: `All tests passed!` + +검증 명령은 이 저장소에서 실행 확인했다. 테스트 캐시 개념이 없는 Dart test라 별도 cache busting은 필요 없다. + +모든 코드 변경 완료 후 반드시 `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 채운다. 이 파일 작성이 구현의 마지막 단계다.