add jenkins_compatibility_boundary task files
This commit is contained in:
parent
ec3162ff7c
commit
7ea841e2ac
6 changed files with 1152 additions and 0 deletions
|
|
@ -0,0 +1,124 @@
|
|||
<!-- task=jenkins_compatibility_boundary/01_core_adapter plan=0 tag=REFACTOR -->
|
||||
|
||||
# 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 |
|
||||
|
|
@ -0,0 +1,284 @@
|
|||
<!-- task=jenkins_compatibility_boundary/01_core_adapter plan=0 tag=REFACTOR -->
|
||||
|
||||
# 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<String, dynamic>? 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<String, dynamic> 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<JenkinsEnvironmentSnapshot?> 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<String, dynamic>? 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<String, dynamic> commonMap({String? workspace}) {
|
||||
return {
|
||||
'workspace': (workspace ?? Directory.current.path).replaceAll('\\', '/'),
|
||||
'jenkinsHome': '',
|
||||
// keep DataCommon compatibility fields
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class FileData {
|
||||
static Map<String, dynamic>? 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`의 구현 에이전트 소유 섹션을 채운다. 이 파일 작성이 구현의 마지막 단계다.
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
<!-- task=jenkins_compatibility_boundary/02+01_file_scheduler_modes plan=0 tag=REFACTOR -->
|
||||
|
||||
# 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 |
|
||||
|
|
@ -0,0 +1,239 @@
|
|||
<!-- task=jenkins_compatibility_boundary/02+01_file_scheduler_modes plan=0 tag=REFACTOR -->
|
||||
|
||||
# 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 <file> --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`의 구현 에이전트 소유 섹션을 채운다. 이 파일 작성이 구현의 마지막 단계다.
|
||||
|
|
@ -0,0 +1,136 @@
|
|||
<!-- task=jenkins_compatibility_boundary/03+01,02_docs_samples plan=0 tag=REFACTOR -->
|
||||
|
||||
# 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 <path>|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 |
|
||||
|
|
@ -0,0 +1,246 @@
|
|||
<!-- task=jenkins_compatibility_boundary/03+01,02_docs_samples plan=0 tag=REFACTOR -->
|
||||
|
||||
# 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 <path>`는 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 <path>|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: <!property.workspace>/ios/Runner.xcworkspace
|
||||
scheme: Runner
|
||||
```
|
||||
|
||||
#### 해결 방법
|
||||
|
||||
README 예제를 현재 iOS 모델에 맞춰 `xcworkspaceFilePath`로 바꾸고, README의 non-comment YAML 예제에 stale field가 돌아오지 않도록 테스트를 추가한다.
|
||||
|
||||
After:
|
||||
|
||||
```yaml
|
||||
- command: BuildiOS
|
||||
id: buildApp
|
||||
param:
|
||||
xcworkspaceFilePath: <!property.workspace>/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`의 구현 에이전트 소유 섹션을 채운다. 이 파일 작성이 구현의 마지막 단계다.
|
||||
Loading…
Reference in a new issue