<!-- task=yaml_validation_contract/01_core_contract plan=1 tag=REVIEW_VALIDATE_CORE -->

# YAML Validation Core Contract Follow-up Plan

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

`CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션 작성은 필수다. 구현 후 검증 명령을 실행하고 실제 출력과 구현 메모를 채운 뒤 active 파일을 그대로 두고 리뷰 준비를 보고한다. 최종 판정, 로그 변환, `complete.log`, archive 이동은 code-review-skill 전용이다.

## 배경

plan 0 리뷰에서 core validation 계약이 일부 malformed YAML에 대해 `YamlValidationResult` 대신 decode 예외를 밖으로 던질 수 있음이 확인되었다. 또한 검증 출력이 실제 stdout/stderr가 아니라 요약으로 기록되어 verification trust가 깨졌다. 이번 follow-up은 Required 항목만 좁게 수정한다.

## 리뷰 결과 요약

- Required: `Application.validateYamlContent`가 `DataBuild.fromJson` 및 이후 validation 초기화 중 발생하는 decode/타입 예외를 failure result로 변환하지 못한다.
- Required: `CODE_REVIEW-cloud-G07.md`의 검증 결과가 실제 stdout/stderr 대신 `All tests passed!` 요약으로 기록되었다.

## 구현 체크리스트

- [ ] [REVIEW_VALIDATE_CORE-1] `Application.validateYamlContent`가 decode/초기화 예외도 `YamlValidationResult.failure`로 반환하게 한다.
- [ ] [REVIEW_VALIDATE_CORE-2] 검증 결과에 지정 명령의 실제 stdout/stderr를 기록해 verification trust를 회복한다.
- [ ] 중간 검증과 최종 검증 명령을 실행하고 실제 결과를 기록한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

## 의존 관계 및 구현 순서

1. `REVIEW_VALIDATE_CORE-1`로 public validation API의 no-throw 계약을 먼저 회복한다.
2. `REVIEW_VALIDATE_CORE-2`로 검증 출력 기록을 실제 실행 출력과 맞춘다.

### [REVIEW_VALIDATE_CORE-1] Decode Exception Guard

#### 문제

`validateYamlContent`는 YAML parse만 `try/catch`로 감싸고, 그 뒤 `DataBuild.fromJson(buildMap)`과 pipeline validation 초기화는 예외가 밖으로 나갈 수 있다.

Before, `lib/oto/application.dart:326`:

```dart
final build = DataBuild.fromJson(buildMap);
final validationContext = ExecutionContext();
final commandMapValidate = _populateCommandMap(build, validationContext);
```

`scheduler: []` 또는 `scheduler.alias` 타입 오류처럼 `DataBuild` decode 단계에서 터지는 YAML은 `YamlValidationResult.failure`가 아니라 TypeError를 노출할 수 있다.

#### 해결 방법

`DataBuild.fromJson` 및 이후 validation 초기화에서 발생할 수 있는 decode/타입 예외를 잡아 `YamlValidationResult.failure`로 반환한다. 가능한 한 기존 phase 규칙을 유지하고, top-level model decode 실패는 `Validate build yaml`로 분류한다.

After 예시:

```dart
DataBuild build;
try {
  build = DataBuild.fromJson(buildMap);
} catch (e) {
  return YamlValidationResult.failure(
    phase: 'Validate build yaml',
    message: e.toString(),
  );
}
```

필요하면 `_validateBuildMap`에 `scheduler` shape 사전 검증을 추가해 더 읽기 쉬운 메시지를 반환한다. 단, 이번 범위는 public validation API가 예외를 던지지 않는 계약 회복에 한정한다.

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

- [ ] `lib/oto/application.dart`: `DataBuild.fromJson` decode 실패를 `YamlValidationResult.failure`로 변환한다.
- [ ] `lib/oto/application.dart`: pipeline validation 초기화 중 예상 가능한 타입 예외도 result로 변환되는지 확인한다.
- [ ] `test/oto_application_test.dart`: malformed scheduler 또는 model decode 실패 YAML이 throw 없이 failure contract를 반환하는 테스트를 추가한다.

#### 테스트 작성

- 작성: `test/oto_application_test.dart`
- 테스트명 후보: `validateYamlContent returns failure contract for malformed scheduler section`
- assertion 목표: 호출이 throw하지 않고 `valid == false`, `phase == 'Validate build yaml'`, `exitCode == 10`, `message`가 비어 있지 않음을 검증한다.

#### 중간 검증

```bash
dart test test/oto_application_test.dart
```

예상 결과: 모든 테스트 통과.

### [REVIEW_VALIDATE_CORE-2] Verification Output Trust Recovery

#### 문제

plan 0의 `CODE_REVIEW-cloud-G07.md`는 테스트 명령 출력으로 `All tests passed!`만 기록했다. 실제 `dart test test/oto_application_test.dart test/oto_core_test.dart` 출력에는 빌드 로그와 실패 케이스 메시지가 포함되므로, code-review 계약의 "실제 stdout/stderr" 요구를 충족하지 못한다.

#### 해결 방법

후속 구현 완료 후 지정 명령을 실제로 다시 실행하고, active `CODE_REVIEW-cloud-G07.md`의 `검증 결과`에 요약이 아닌 실제 stdout/stderr를 기록한다. 출력이 길어도 임의 요약으로 대체하지 않는다.

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

- [ ] `agent-task/yaml_validation_contract/01_core_contract/CODE_REVIEW-cloud-G07.md`: 중간/최종 검증 출력에 실제 command output을 기록한다.

#### 테스트 결정

코드 테스트는 `REVIEW_VALIDATE_CORE-1`에서 추가한다. 이 항목의 검증은 후속 review 파일에 기록된 출력과 실제 명령 재실행 결과의 일치 여부로 확인한다.

#### 중간 검증

```bash
dart analyze
```

예상 결과: `No issues found!`

```bash
dart test test/oto_application_test.dart test/oto_core_test.dart
```

예상 결과: 모든 테스트 통과. 실제 stdout/stderr를 review 파일에 기록한다.

## 수정 파일 요약

| 파일 | 항목 |
|------|------|
| `lib/oto/application.dart` | REVIEW_VALIDATE_CORE-1 |
| `test/oto_application_test.dart` | REVIEW_VALIDATE_CORE-1 |
| `agent-task/yaml_validation_contract/01_core_contract/CODE_REVIEW-cloud-G07.md` | REVIEW_VALIDATE_CORE-2 |

## 최종 검증

```bash
dart analyze
```

예상 결과: `No issues found!`

```bash
dart test test/oto_application_test.dart test/oto_core_test.dart
```

예상 결과: 모든 테스트 통과. Dart test cache 개념은 적용하지 않는다.

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