runner 출력 경계 분리의 첫 계약 작업을 완료하고 후속 subtask와 로드맵 상태를 함께 기록한다. workspace 포트와 local smoke 기준도 독립 Control Plane 방향에 맞춰 정리한다.
7.3 KiB
7.3 KiB
Plan - REFACTOR
Roadmap Targets
- Milestone:
agent-roadmap/phase/independent-control-plane/milestones/runner-output-boundary.md - Task ids:
pipeline: pipeline domain이 CLI 구현체 대신 output port를 사용하도록 분리한다. 검증: runner analyze와 pipeline 관련 테스트가 통과한다.
- Completion mode: check-on-pass
배경
이 작업은 01_output_port_contract 완료 후 진행한다. pipeline domain에서 CLI 출력 구현 import와 Application.instance.printBuildStep 직접 호출을 제거하고 explicit ExecutionContext.output을 사용한다.
Roadmap Dependency
- predecessor:
agent-task/m-runner-output-boundary/01_output_port_contract/complete.log - 상태: 작성 시점에는 미충족. 구현 시작 전 active 또는 archive complete.log를 확인한다.
분석 결과
읽은 파일
agent-roadmap/current.mdagent-roadmap/phase/independent-control-plane/milestones/runner-output-boundary.mdagent-ops/rules/project/domain/pipeline/rules.mdagent-ops/rules/project/domain/core/rules.mdagent-test/local/pipeline-smoke.mdagent-test/local/core-smoke.mdapps/runner/lib/oto/core/execution_context.dartapps/runner/lib/oto/pipeline/pipeline.dartapps/runner/lib/oto/pipeline/pipeline_exe.dartapps/runner/lib/oto/pipeline/pipeline_exe_handle.dartapps/runner/lib/oto/pipeline/pipeline_foreach.dartapps/runner/test/oto_core_test.dart
테스트 환경 규칙
- test_env:
local - 읽은 env rule:
agent-test/local/rules.md - 매칭 profile:
pipeline-smoke,core-smoke - 적용 명령:
cd apps/runner && dart analyze,cd apps/runner && dart test, 최소test/oto_core_test.dart - pipeline 전용 테스트가 확인되지 않아 변경 영향이 있는 경우 runner 전체 test가 필요하다는 규칙을 적용한다.
테스트 커버리지 공백
- pipeline 출력이 explicit context output으로 들어가는지 확인하는 테스트가 없다.
apps/runner/test/oto_core_test.dart에 recording output 기반 regression test를 추가한다. - CLI 출력 보존은 다음
03작업에서 검증한다.
심볼 참조
- 제거 대상 direct dependency:
apps/runner/lib/oto/pipeline/pipeline_exe.dart:package:oto/cli/cli.dart,Application.instance.printBuildStepapps/runner/lib/oto/pipeline/pipeline_exe_handle.dart:package:oto/cli/cli.dart,Application.instance.printBuildStepapps/runner/lib/oto/pipeline/pipeline_foreach.dart:package:oto/cli/cli.dart,CLI.println
Application.log는 로그 파일 경계로 남길 수 있으나 output port와 중복될 경우 최소 변경으로 유지한다.
분할 판단
- split decision policy 평가 완료.
- 이 subtask는
02+01_pipeline_output_port이며 predecessor01이 필요하다. 03+01,02_core_cli_adapter는 이 작업 완료 후 DataComposer/Application/CLI adapter를 마무리한다.
범위 결정 근거
- pipeline domain만 수정한다.
- DataComposer compose signature와 Application CLI adapter 연결은 제외한다.
- command domain의
CLI.println직접 호출은 마일스톤 범위 밖이다.
빌드 등급
- build lane:
local-G06 - review lane:
local-G06 - 근거: call-site 수는 적지만 pipeline 실행 이벤트와 explicit context 회귀 위험이 있어 focused regression test가 필요하다.
구현 체크리스트
01_output_port_contractcomplete.log를 확인한다.pipeline_exe.dart,pipeline_exe_handle.dart,pipeline_foreach.dart에서 CLI import와 CLI direct call을 제거한다.- pipeline 출력은
runtimeContext.output.line또는runtimeContext.output.buildStep을 사용한다. - explicit context output regression test를 추가한다.
cd apps/runner && dart analyze,cd apps/runner && dart test test/oto_core_test.dart,cd apps/runner && dart test를 실행한다.- CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.
의존 관계 및 구현 순서
- 디렉터리명
02+01_pipeline_output_port기준 predecessor는01_output_port_contract하나다. - 구현 시작 전
agent-task/m-runner-output-boundary/01_output_port_contract/complete.log또는 archive의 같은 subtask complete.log를 확인한다.
수정 파일 요약
| 파일 | 항목 |
|---|---|
apps/runner/lib/oto/pipeline/pipeline_exe.dart |
REFACTOR-1 |
apps/runner/lib/oto/pipeline/pipeline_exe_handle.dart |
REFACTOR-1 |
apps/runner/lib/oto/pipeline/pipeline_foreach.dart |
REFACTOR-1 |
apps/runner/test/oto_core_test.dart |
REFACTOR-1 |
[REFACTOR-1] Pipeline Output Port Rollout
문제
pipeline_exe.dart는 condition 출력에 CLI.println을 직접 호출하고, pipeline_exe.dart와 pipeline_exe_handle.dart는 Application.instance.printBuildStep을 직접 호출한다. pipeline_foreach.dart도 CLI를 직접 호출한다.
Before:
// apps/runner/lib/oto/pipeline/pipeline_exe.dart:41
static Future printCondition(...) async {
await CLI.println('[Pipeline-$syntax]', color: Color.magentaStrong);
Application.log(...);
}
해결 방법
PipelineExecutor.runtimeContext.output을 사용한다. 색은 RunnerOutputStyle.progress 등 선행 계약의 neutral style로 매핑한다.
After:
await runtimeContext.output.line(
'[Pipeline-$syntax]',
style: RunnerOutputStyle.progress,
);
printCondition은 static이라 context를 받을 수 없으면 signature에 ExecutionContext? context를 추가하고 call site에서 runtimeContext를 넘긴다. 호출부를 모두 검색해 누락 없이 갱신한다.
수정 파일 및 체크리스트
pipeline_exe.dartimport에서package:oto/cli/cli.dart제거pipeline_exe_handle.dartimport에서package:oto/cli/cli.dart제거pipeline_foreach.dartimport에서package:oto/cli/cli.dart제거Application.instance.printBuildStep직접 호출을 output port 호출로 대체CLI.println직접 호출을 output port 호출로 대체apps/runner/test/oto_core_test.dart에 recording output으로Phase Start또는 foreach completion output 검증 추가
테스트 작성
- 작성:
apps/runner/test/oto_core_test.dart - 테스트 이름 후보:
pipeline emits progress through explicit context output port - 목표: explicit
ExecutionContext에 recording output을 주입한 뒤 pipeline 실행 시 output이 해당 context로 들어오고 singleton CLI 경계에 의존하지 않음을 확인한다.
중간 검증
cd apps/runner && dart analyze
cd apps/runner && dart test test/oto_core_test.dart
최종 검증
cd apps/runner && dart analyze
cd apps/runner && dart test
모든 코드 변경 완료 후 반드시 CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 채운다. 이 파일 작성이 구현의 마지막 단계다.