docs: align guidance with simplified agent and harness workflow
This commit is contained in:
+91
-117
@@ -1,84 +1,46 @@
|
||||
# Harness 운영 가이드
|
||||
|
||||
## Requirements
|
||||
## 목적과 준비 환경
|
||||
|
||||
Windows와 Codex CLI가 필요하다. Executor는 Python 3.10 이상을 사용하며, 이 저장소의
|
||||
계약 테스트는 표준 `tomllib`을 사용하므로 검증 환경은 Python 3.11 이상으로 준비한다.
|
||||
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 환경과 dependency 경로는 [AGENTS.md](../AGENTS.md)의
|
||||
최소 검증 진입점을 따른다.
|
||||
사용한다. MSVC x64 developer 환경에서 `FESA_GTEST_SOURCE_DIR`, `MKL_DIR`, `TBB_DIR`,
|
||||
`HDF5_DIR`를 설치된 dependency 경로로 설정한다. 상세 기준은
|
||||
[프로젝트 지침](../AGENTS.md)의 최소 검증 진입점을 따른다.
|
||||
|
||||
역할·승인·상태 전이는 [Agent 계약](SOLVER_AGENT_DESIGN.md)과
|
||||
[Harness skill](../.agents/skills/harness/SKILL.md)을 따른다. 이 문서는 설치·실행 참고이며
|
||||
solver Feature의 9개 stage와 evidence gate를 대신하지 않는다.
|
||||
## 명시적 실행과 설정 선택
|
||||
|
||||
## 프로젝트 자동 감지
|
||||
|
||||
프로젝트 형식은 다음 순서로 결정한다: `.harness/config.json`의 명시적 type, 루트의
|
||||
CMake metadata, 하나의 `.sln`, 하나의 `.vcxproj` 순서다. C/C++가 아닌 저장소는
|
||||
건너뛰며, C/C++ 파일은 있지만 CMake/solution metadata가 없는 orphan-C++ 저장소는
|
||||
오류로 처리한다.
|
||||
|
||||
설정 파일은 선택 사항이다. 기본 자동 감지와 `.harness/build` 경로를 그대로 사용할
|
||||
때는 만들지 않아도 된다. 프로젝트별 override가 필요하면 다음처럼 예시를 복사한다.
|
||||
저장소 루트에서 구성된 전체 검증을 한 번 실행한다.
|
||||
|
||||
```powershell
|
||||
Copy-Item .harness/config.example.json .harness/config.json
|
||||
python scripts/execute.py
|
||||
```
|
||||
|
||||
승인된 Feature와 Coordinator dispatch에 따라 Planning Agent가 할당된 phase 파일을
|
||||
작성한다. 일반 계획 파일 작성에 반복 승인을 요구하지 않는다. 실행까지 할당된 경우에만
|
||||
다음 명령을 사용하며, 계획 작성 요청만으로 Executor를 시작하지 않는다.
|
||||
개발 중 focused check는 선택된 backend의 실제 명령을 직접 실행한다. 솔버 기능 완료 시
|
||||
구성된 전체 build/test와 계약상 필수 reference 비교를 수행하고 이후 변경·실패가 없으면
|
||||
반복하지 않는다. 문서만 변경하는 작업에서는 정적 검토를 하고 build/test를 실행하지 않는다.
|
||||
|
||||
```powershell
|
||||
python scripts/execute.py <phase-name>
|
||||
```
|
||||
Runner는 자신의 script 위치를 기준으로 저장소 root를 정하고 `.harness/config.json`을
|
||||
읽는다. 설정이 없으면 기본 자동 감지를 사용한다. 선택 순서는 명시한 `projectType`,
|
||||
설정된 CMake source directory의 metadata, root의 단일 `.sln`, 단일 `.vcxproj`다.
|
||||
여러 solution/project로 선택이 모호하면 명시 설정이 필요하다. C++ source 전체를
|
||||
scan하거나 metadata 없는 C++ 파일의 존재로 별도 gate를 적용하지 않는다.
|
||||
|
||||
`--push`는 해당 원격 push를 사용자가 명시적으로 승인했을 때만 추가한다. 실행 전
|
||||
Git top-level은 Harness root와 같고 선택된 phase 제어 파일 밖의 worktree는 clean이어야
|
||||
한다. 실행 중 동시 편집과 커밋 범위의 한계는 [동작 과정](HARNESS_WORKFLOW.md)을 따른다.
|
||||
현재 [config 예시](../.harness/config.example.json)는 `projectType=cmake`와
|
||||
`cmake.sourceDir=.`만 지정한다. 개인 설정이 필요할 때 참고하되 기존 설정을 무조건
|
||||
덮어쓰지 않는다. Preset 없는 기본 binary directory는 `.harness/build`다.
|
||||
|
||||
모든 `pending` Step에는 승인된 정확한 상대 파일 목록인 `owned_paths`가 필요하다.
|
||||
누락된 기존 phase는 Planning의 할당된 준비 작업에서 목록을 보완한 뒤 실행한다.
|
||||
`[]`는 구현 파일 변경이 없음을 뜻하며 완료 이력에는 목록을 소급 추가하지 않는다.
|
||||
Executor는 실행 후와 staging/commit 경계에서 소유권을 검사하며 범위 밖 변경은
|
||||
보존하고 중단한다. 상세 schema와 제한은 [Harness skill](../.agents/skills/harness/SKILL.md)을 따른다.
|
||||
## FESA CMake preset 설정
|
||||
|
||||
Executor가 시작하는 Codex 세션은 기본적으로 `workspace-write` sandbox를 사용한다.
|
||||
Windows native sandbox에서 MSVC compiler-id의 `cl.exe`가 정지하는 것이 재현되고 같은
|
||||
명령이 sandbox 밖에서 정상 완료되는 경우에만, 사용자 승인을 받은 격리된 clean
|
||||
linked Git worktree에서 다음처럼 해당 실행에 한정해 fallback을 지정할 수 있다.
|
||||
|
||||
```powershell
|
||||
$env:FEM_HARNESS_CODEX_SANDBOX = "danger-full-access"
|
||||
python scripts/execute.py <phase-name> --approve-danger-full-access
|
||||
Remove-Item Env:FEM_HARNESS_CODEX_SANDBOX
|
||||
```
|
||||
|
||||
허용값은 `workspace-write`와 `danger-full-access`뿐이다. 후자는 Codex Step에 workspace
|
||||
밖의 파일 접근 권한도 부여하므로 일반 기본값으로 설정하지 않는다. 어느 모드에서도
|
||||
`.codex/hooks.json`의 등록된 hook을 비활성화하지 않는다. 환경변수만으로 권한이 승인되지
|
||||
않으며 Executor는 승인 flag가 없거나 primary/dirty worktree인 권한 상승 실행을 거부한다.
|
||||
|
||||
Stop은 유효한 동일 session/turn 편집 기록의 대상이 모두 저장소 내부 `.md`일 때만
|
||||
build/test를 생략한다. 기록 누락·손상 또는 비문서 편집은 정상 검증 경로를 따른다.
|
||||
Shell 쓰기나 편집 기록 없는 읽기 전용 요청도 자동 생략을 보장하지 않는다. 문서 작업에서
|
||||
사용자가 실행을 제외하면 수동으로 Hook·build/test를 실행하지 않고 미검증 사실을 보고한다.
|
||||
|
||||
## Harness Python 검증
|
||||
|
||||
이 저장소의 테스트와 최종 acceptance 검증은 pytest를 시스템 Python에 설치하지 않고
|
||||
다음 명령으로 실행한다.
|
||||
|
||||
```powershell
|
||||
uv run --with pytest python -B -m pytest -v -rs
|
||||
```
|
||||
|
||||
## CMake preset 설정
|
||||
|
||||
`projectType`을 `cmake`로 지정하거나 자동 감지를 사용한다. `cmake.sourceDir`,
|
||||
`binaryDir`, `configurePreset`, `buildPreset`, `testPreset`은 preset을 사용할 때 함께
|
||||
지정해야 한다. 빌드 산출물은 저장소의 `.harness/build/`처럼 격리된 경로에 둔다.
|
||||
FESA의 현재 [CMakePresets.json](../CMakePresets.json)을 사용하려면 다음 필드를
|
||||
`.harness/config.json`에 함께 지정한다. Preset 파일의 존재나 config 예시 복사만으로
|
||||
Runner가 preset 이름을 선택하지는 않는다.
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -94,6 +56,9 @@ uv run --with pytest python -B -m pytest -v -rs
|
||||
}
|
||||
```
|
||||
|
||||
`configurePreset`, `buildPreset`, `testPreset`, `binaryDir`는 함께 지정해야 한다.
|
||||
이에 대응하는 backend 명령은 다음과 같다.
|
||||
|
||||
```powershell
|
||||
cmake --preset windows-msvc-ninja-debug
|
||||
cmake --build --preset windows-msvc-ninja-debug
|
||||
@@ -101,10 +66,8 @@ ctest --preset windows-msvc-ninja-debug --show-only=json-v1
|
||||
ctest --preset windows-msvc-ninja-debug --output-on-failure
|
||||
```
|
||||
|
||||
위 예시는 현재 [CMakePresets.json](../CMakePresets.json)과
|
||||
[config 예시](../.harness/config.example.json)에 맞춘다. Preset 파일이 존재하는 것만으로
|
||||
Stop이 그 preset을 선택하지는 않는다. 아래는 preset을 쓰지 않는 adapter의 명령 형태이며,
|
||||
FESA에서는 dependency 경로와 승인된 build 구성을 함께 확인한다.
|
||||
아래는 preset 없는 CMake adapter의 기본 명령 형태다. FESA에서는 승인된 MSVC x64 Debug
|
||||
구성과 dependency 경로를 함께 확인한다.
|
||||
|
||||
```powershell
|
||||
cmake -S . -B .harness/build -A x64
|
||||
@@ -113,14 +76,14 @@ 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 검증을 대체 승인하지 않는다.
|
||||
|
||||
`projectType`을 `msbuild`로 설정하면 `msbuild.solution`, `configuration`, `platform`을
|
||||
지정한다. 직접 MSBuild 프로젝트에서는 `msbuild.testCommand`가 필수이며, 테스트 실행
|
||||
파일과 인수를 JSON 배열로 적는다.
|
||||
다음은 재사용 Harness adapter의 예시다. FESA 제품 검증은 CMake/CTest를 사용하며
|
||||
solution-only MSBuild를 승인된 대체 검증으로 간주하지 않는다.
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -135,46 +98,57 @@ ctest --test-dir .harness/build -C Debug --output-on-failure
|
||||
}
|
||||
```
|
||||
|
||||
`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 <phase>` 호출과 `--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
|
||||
MSBuild.exe MyProject.sln /m /p:Configuration=Debug /p:Platform=x64
|
||||
.\build\tests\Debug\MyProjectTests.exe
|
||||
uv run --with pytest python -B -m pytest -v -rs
|
||||
```
|
||||
|
||||
## TDD 확장
|
||||
|
||||
`tdd.testRoots`와 `tdd.testPatterns`로 테스트 위치와 이름을 확장한다. 패턴마다
|
||||
`{stem}`이 필요하다. `main`, 테스트, 외부 의존성, 생성 파일, build directory 같은
|
||||
기본 제외 항목은 Harness가 관리하며, `tdd.exclude`의 사용자 제외 항목은 이를
|
||||
대체하지 않고 추가한다.
|
||||
|
||||
```json
|
||||
{
|
||||
"version": 1,
|
||||
"tdd": {
|
||||
"testRoots": ["tests", "integration-tests"],
|
||||
"testPatterns": ["{stem}_test.cpp", "test_{stem}.cpp"],
|
||||
"exclude": ["legacy/generated/**"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 실패 복구
|
||||
|
||||
Executor는 명시적 `error/blocked`를 비정상 종료에서도 보존하며 자동 재시도하지 않는다.
|
||||
인식된 sandbox helper 환경 오류는 종료 코드 0에서도 Step과 상위 phase를 `blocked`로
|
||||
기록한다. 실제 wrapper timeout으로 결과를 받지 못했을 때만 최초 포함 최대 두 번 시도한다.
|
||||
원인 미분류 nonzero와 `completed`/nonzero 불일치는 `error`다. 환경 차단은 종료 코드 2,
|
||||
일반 실패는 1이며 preflight 실패는 branch/state 변경 전에 반환한다.
|
||||
|
||||
- Visual Studio C++ workload가 없으면 Installer에서 Desktop development with C++를 설치한 뒤 다시 실행한다.
|
||||
- solution 또는 project가 여러 개라서 모호하면 `projectType`과 `msbuild.solution`을 명시한다.
|
||||
- MSVC가 아닌 컴파일러가 감지되면 MSVC Developer Command Prompt에서 실행하거나 toolchain을 MSVC로 전환한다.
|
||||
- CTest가 0개 테스트를 보고하면 `enable_testing()`과 테스트 등록을 확인한다.
|
||||
- 직접 MSBuild 구성에 test command가 없으면 `msbuild.testCommand` 배열을 추가한다.
|
||||
- timeout 또는 명령 실패 시 Stop 응답의 stage, 안전한 argv 배열, 작업 디렉터리,
|
||||
종료 코드와 출력 tail을 확인한다. 실행이 할당된 범위에서만 재현 명령을 수행하며
|
||||
문서 작업의 검증 제외 지시를 덮어쓰지 않는다. Stop은 별도의 빌드 로그 파일을 만들지 않는다.
|
||||
- 실패 분류와 재시작 결정은 Coordinator가 기록한다. Planning Agent는 명시적으로 할당된
|
||||
복구 작업에서만 현재 실패 Step의 status를 `pending`으로 바꾸고, Executor가 재시작 시
|
||||
오래된 outcome 필드와 timestamp를 정리하되 `attempt_history`는 보존한다. 실패 evidence를 먼저 보존하며
|
||||
상세 절차는 [Harness skill](../.agents/skills/harness/SKILL.md)의 Recovery and handoff를 따른다.
|
||||
실제 검사 결과와 미실행 항목을 구분해 보고한다. 문서만 갱신할 때는 이 명령을 실행하지 않는다.
|
||||
|
||||
Reference in New Issue
Block a user