# Harness 운영 가이드 ## 목적과 준비 환경 Harness는 명시적으로 호출하는 repository build/test 실행기다. [Agent 운영](SOLVER_AGENT_DESIGN.md)과 [Harness skill](../.agents/skills/harness/SKILL.md)에 따라 필요한 검증을 수행하며 내부 Codex 호출, phase 관리, 자동 Git 처리와 대화 종료 hook을 사용하지 않는다. 현재 운영 결정은 [ADR-028](ADR.md#adr-028)을 따른다. Runner에는 Windows와 Python 3.10 이상이 필요하다. 저장소의 `tomllib` 기반 Python 검사는 Python 3.11 이상을 사용한다. Runner 자체는 Codex CLI를 필요로 하지 않는다. FESA는 Visual Studio의 Desktop development with C++ 워크로드, CMake/CTest와 Ninja를 사용한다. MSVC x64 developer 환경에서 `FESA_GTEST_SOURCE_DIR`, `MKL_DIR`, `TBB_DIR`, `HDF5_DIR`를 설치된 dependency 경로로 설정한다. 상세 기준은 [프로젝트 지침](../AGENTS.md)의 최소 검증 진입점을 따른다. ## 명시적 실행과 설정 선택 저장소 루트에서 구성된 전체 검증을 한 번 실행한다. ```powershell python scripts/execute.py ``` 개발 중 focused check는 선택된 backend의 실제 명령을 직접 실행한다. 솔버 기능 완료 시 구성된 전체 build/test와 계약상 필수 reference 비교를 수행하고 이후 변경·실패가 없으면 반복하지 않는다. 문서만 변경하는 작업에서는 정적 검토를 하고 build/test를 실행하지 않는다. Runner는 자신의 script 위치를 기준으로 저장소 root를 정하고 `.harness/config.json`을 읽는다. 설정이 없으면 기본 자동 감지를 사용한다. 선택 순서는 명시한 `projectType`, 설정된 CMake source directory의 metadata, root의 단일 `.sln`, 단일 `.vcxproj`다. 여러 solution/project로 선택이 모호하면 명시 설정이 필요하다. C++ source 전체를 scan하거나 metadata 없는 C++ 파일의 존재로 별도 gate를 적용하지 않는다. 현재 [config 예시](../.harness/config.example.json)는 `projectType=cmake`와 `cmake.sourceDir=.`만 지정한다. 개인 설정이 필요할 때 참고하되 기존 설정을 무조건 덮어쓰지 않는다. Preset 없는 기본 binary directory는 `.harness/build`다. ## FESA CMake preset 설정 FESA의 현재 [CMakePresets.json](../CMakePresets.json)을 사용하려면 다음 필드를 `.harness/config.json`에 함께 지정한다. Preset 파일의 존재나 config 예시 복사만으로 Runner가 preset 이름을 선택하지는 않는다. ```json { "version": 1, "projectType": "cmake", "cmake": { "sourceDir": ".", "binaryDir": ".harness/build-ninja-msvc-debug", "configurePreset": "windows-msvc-ninja-debug", "buildPreset": "windows-msvc-ninja-debug", "testPreset": "windows-msvc-ninja-debug" } } ``` `configurePreset`, `buildPreset`, `testPreset`, `binaryDir`는 함께 지정해야 한다. 이에 대응하는 backend 명령은 다음과 같다. ```powershell cmake --preset windows-msvc-ninja-debug cmake --build --preset windows-msvc-ninja-debug ctest --preset windows-msvc-ninja-debug --show-only=json-v1 ctest --preset windows-msvc-ninja-debug --output-on-failure ``` 아래는 preset 없는 CMake adapter의 기본 명령 형태다. FESA에서는 승인된 MSVC x64 Debug 구성과 dependency 경로를 함께 확인한다. ```powershell cmake -S . -B .harness/build -A x64 cmake --build .harness/build --config Debug ctest --test-dir .harness/build -C Debug --show-only=json-v1 ctest --test-dir .harness/build -C Debug --output-on-failure ``` Runner는 configure 후 MSVC compiler metadata를 확인하고 CTest discovery가 0개이면 실패로 처리한다. Build/test 성공이 물리·수치 correctness나 별도 필수 reference 비교의 통과를 대신하지 않는다. Runner는 Feature 문서에서 추가 비교 명령을 추론하지 않는다. ## 직접 MSBuild 설정 다음은 재사용 Harness adapter의 예시다. FESA 제품 검증은 CMake/CTest를 사용하며 solution-only MSBuild를 승인된 대체 검증으로 간주하지 않는다. ```json { "version": 1, "projectType": "msbuild", "msbuild": { "solution": "MyProject.sln", "configuration": "Debug", "platform": "x64", "testCommand": ["build/tests/Debug/MyProjectTests.exe"] } } ``` `msbuild.testCommand`는 필수 argv 배열이며 실행 파일은 repository-relative 경로로 지정한다. 선택한 solution/project를 build한 뒤 testCommand를 한 번 실행한다. ## 결과와 실패 진단 | 상황 | Runner 결과 | | --- | --- | | 구성된 build/test와 결과 검사가 모두 성공 | exit 0, 명령·cwd·exit code와 test 출력 요약 | | 잘못된 config, 모호한 감지, toolchain/adapter 오류, backend 실패·timeout | exit 1 | | 명시한 projectType의 metadata가 없음 | exit 1 | | Non-MSVC compiler 또는 CTest 0개/잘못된 discovery 결과 | exit 1 | | 자동 감지에서 CMake/MSBuild metadata가 없음 | `not configured`, exit 2 | | 지원하지 않는 CLI 인자 | usage error, exit 2; 검증 미시작 | Backend nonzero는 실패 진단에 원래 값으로 남지만 runner의 반환값은 1이다. 대상 부재나 미실행을 검증 통과로 표시하지 않는다. 실패 시 stage, argv, cwd와 가능한 출력 tail을 확인한다. 실패 후 자동 재시도나 후속 단계를 실행하지 않는다. - Visual Studio 도구가 없으면 C++ workload와 설치 경로를 확인한다. - Solution/project 선택이 모호하면 `projectType`, `msbuild.solution`을 명시한다. - Compiler가 MSVC가 아니면 선택된 환경과 toolchain 설정을 확인한다. - CTest가 0개이면 `enable_testing()`과 테스트 등록을 확인한다. - MSBuild test command가 없으면 실제 테스트 실행 파일과 인수를 설정한다. - Timeout·실패 원인은 현재 구현 owner가 수정한다. 새 근거나 변경 없이 반복 실행하지 않는다. Runner 전체 deadline은 config·discovery·toolchain 탐색을 포함해 1,800초다. 각 명령에는 남은 전체 시간과 명령별 timeout 중 짧은 값을 적용한다. 실행·검사 경계는 [동작 과정](HARNESS_WORKFLOW.md)을 따른다. ## 이전 운영 방식에서 달라진 점 옛 `python scripts/execute.py ` 호출과 `--push`, `--approve-danger-full-access` 인자는 usage error로 거부한다. Phase import나 상태 migration은 제공하지 않으며 기존 `phases/` 기록을 읽거나 수정하지 않는다. Legacy `tdd` config는 설정 로드 때 폐기 안내를 한 번 출력하고 무시한다. `testRoots`·`testPatterns`·`exclude`에 의한 대응 파일명 gate는 없다. 개인 config는 자동 수정하지 않으므로 사용자가 필요할 때 해당 항목을 제거할 수 있다. 전용 phase executor, 자동 branch/commit/push·retry, PreToolUse/Stop과 자체 sandbox 승인 환경변수는 사용하지 않는다. Git 상태를 변경하거나 commit할 권한은 runner 실행에서 생기지 않는다. Config·preset·명령은 검토할 실행 입력이며 `shell=False`와 경로 검사는 완전한 sandbox가 아니다. 실제 도구 권한과 외부 실행의 명시적 승인 경계는 유지한다. ## Harness Python 검증 Harness 구현을 변경하여 Python 검증이 필요할 때 다음 명령을 사용한다. 개발 중에는 관련 검사만 선택하고 전체 검사가 필요한 최종 변경 후 한 번 실행한다. ```powershell uv run --with pytest python -B -m pytest -v -rs ``` 실제 검사 결과와 미실행 항목을 구분해 보고한다. 문서만 갱신할 때는 이 명령을 실행하지 않는다.