Files
Agentic-AI-Template/Codex/Coding/harness framework cpp/docs/ENVIRONMENT_SETUP.md
T
2026-09-08 10:30:07 +09:00

398 lines
22 KiB
Markdown

# MSVC C++ Harness 환경 구축 가이드
이 문서는 Windows에서 이 Harness framework를 설치하고, C++ 제품 저장소의
MSVC 빌드·테스트 및 Codex step 실행을 준비하는 절차를 설명한다.
명령은 별도 표시가 없으면 **대상 저장소 루트의 PowerShell**에서 실행한다.
현재 저장소에는 실행기, 훅, 설정 예제가 있으며 실제 C++ 제품 소스, CMake/Visual
Studio 프로젝트, 실행할 `phases/`, Python 테스트 디렉터리는 없다. 따라서 도구
설치 확인과 실제 제품 빌드 성공을 구분해야 한다. 아래 프로젝트명·preset 이름·경로는
설정 형식을 보여 주는 예시이며, 제품의 MSVC toolset·C++ 표준·테스트 프레임워크는
아직 확정되지 않았다.
## 1. 필요한 환경
| 구분 | 요구 사항 | 용도 및 확인 기준 |
|---|---|---|
| 운영체제 | 선택한 Visual Studio가 지원하는 Windows | 이 가이드는 Windows 네이티브 실행과 x64 빌드를 기준으로 한다. 현재 도구 탐색은 `vswhere.exe`, `MSBuild.exe`를 사용한다. |
| 셸 | PowerShell | 설치 점검과 Windows 훅 명령 실행. 아래 UTF-8 파일 작성 예제는 PowerShell 7 기준이다. |
| Git | Windows에서 실행 가능한 Git | 저장소 탐색, branch 전환, 자동 commit. `--push` 사용 시에만 원격 저장소 인증이 추가로 필요하다. |
| Python | 3.10 이상, `python` 명령으로 실행 가능 | 실행기와 훅은 표준 라이브러리만 사용한다. 일반 실행에 `pip install`이나 가상환경은 필수가 아니다. |
| Codex CLI | 아래 옵션·훅 호환성 점검을 통과하는 버전 | `codex exec`, JSON 출력, stdin 프롬프트와 프로젝트 훅을 지원해야 한다. 로그인과 서비스 네트워크 접근이 필요하다. |
| C++ 빌드 도구 | Visual Studio 또는 Build Tools의 MSVC x64/x86 도구, MSBuild, Windows SDK | Visual Studio Installer에서 C++ 워크로드를 설치한다. VS Code만 설치해서는 충족되지 않는다. |
| CMake 방식 | CMake와 CTest 3.20 이상, 제품이 요구하는 버전 이상 | `ctest --test-dir`와 build/test preset 기능에 필요한 하한이다. generator와 preset schema가 더 높은 버전을 요구할 수 있다. |
| MSBuild 방식 | 실제 `.sln` 또는 `.vcxproj`, 테스트 실행 명령 | CMake/CTest는 이 방식의 Harness 검증에 필수가 아니다. |
| 선택 도구 | Node.js/npm, Ninja, pytest/uv | Node.js/npm은 Codex의 npm 설치 방식을 선택할 때, Ninja는 해당 generator를 쓸 때만 필요하다. pytest/uv는 Harness 자체 테스트가 있는 checkout에서 사용한다. |
CMake 기능의 버전 근거는 [CMake 3.20 릴리스 노트](https://cmake.org/cmake/help/v3.20/release/3.20.html)와
[CTest 명령 문서](https://cmake.org/cmake/help/latest/manual/ctest.1.html)를 참고한다.
Windows·Visual Studio·Codex의 정확한 지원 버전 조합은 저장소에서 고정하지 않았다.
팀에서 검증한 버전은 제품 도입 시 별도로 기록한다.
## 2. 기본 도구 설치
### Git과 Python
1. [Git for Windows 공식 설치 페이지](https://git-scm.com/install/windows)에서 설치하고
PowerShell과 외부 프로그램에서 `git`을 실행할 수 있도록 PATH를 설정한다.
2. [Python Windows 공식 배포 페이지](https://www.python.org/downloads/windows/)에서
3.10 이상의 Python을 설치한다. 실행기뿐 아니라 자식 훅에서도 같은 Python을 찾도록
실제 설치 디렉터리를 사용자 PATH에 등록한다.
3. 새 PowerShell 창을 열고 확인한다.
```powershell
git --version
python --version
python -c "import sys; print(sys.executable); assert sys.version_info >= (3, 10)"
Get-Command git, python | Select-Object Name, Source
```
`python`이 Microsoft Store를 열거나 실행되지 않으면 Windows의 앱 실행 별칭과
PATH 순서를 확인한다. `py`만 동작하는 상태는 충분하지 않다. 현재 Windows 훅이
`python` 명령을 사용하기 때문이다. 가상환경을 쓰면 활성화한 동일 터미널에서
Harness를 실행한다.
### Visual Studio와 C++ 도구
1. [Microsoft의 MSVC 설치 안내](https://learn.microsoft.com/en-us/cpp/overview/acquire-msvc)를
따라 Visual Studio Installer를 실행한다. IDE가 필요하면 Visual Studio,
명령줄 빌드만 필요하면 Build Tools 설치를 선택한다.
2. **C++를 사용한 데스크톱 개발(Desktop development with C++)** 워크로드를 선택한다.
3. 설치 세부 정보에서 MSVC x64/x86 빌드 도구, MSBuild, 제품이 요구하는 Windows SDK가
포함되는지 확인한다. 기존 제품이면 해당 `PlatformToolset`과 SDK 버전을 설치한다.
4. CMake 방식이면 **Windows용 C++ CMake 도구**도 선택하거나 CMake를 별도 설치한다.
설치 후 아래 조회에서 실제 설치 경로와 `MSBuild.exe` 경로가 나와야 한다.
```powershell
$vswhere = Join-Path ${env:ProgramFiles(x86)} 'Microsoft Visual Studio/Installer/vswhere.exe'
Test-Path -LiteralPath $vswhere
& $vswhere -latest -products '*' -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath
& $vswhere -latest -products '*' -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -find 'MSBuild\**\Bin\MSBuild.exe'
```
Harness도 이 C++ component ID로 설치를 찾는다. 여러 Visual Studio 설치가 있으면
조건에 맞는 최신 설치를 선택하며, `.harness/config.json`에는 Visual Studio 설치 경로를
고정하는 필드가 없다. 특정 toolset 선택은 제품의 preset 또는 프로젝트 metadata에서 한다.
### CMake 사용 시 추가 점검
Harness는 PATH의 `cmake.exe`와 `ctest.exe`를 우선하고, 없으면 탐색한 Visual Studio의
번들 디렉터리를 사용한다. 아래는 번들 경로를 현재 터미널 PATH에 추가하는 예시다.
```powershell
$vsInstall = & $vswhere -latest -products '*' -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath
$cmakeBin = Join-Path $vsInstall 'Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/bin'
if (Test-Path -LiteralPath (Join-Path $cmakeBin 'cmake.exe')) {
$env:PATH = "$cmakeBin;$env:PATH"
}
cmake --version
ctest --version
Get-Command cmake, ctest | Select-Object Name, Source
```
두 도구가 같은 CMake 배포본을 가리키도록 맞춘다. 새 터미널에서도 수동 명령을
사용하려면 해당 디렉터리를 사용자 PATH에 등록한다.
Visual Studio generator와 직접 MSBuild는 설치된 도구를 활용한다. Ninja preset이나
`cl.exe` 직접 실행을 쓰는 경우에는 **Developer PowerShell for VS** 또는
**x64 Native Tools Command Prompt for VS**로 개발 환경을 먼저 연다. 명령 프롬프트에서
이 문서의 예제를 실행하려면 그 창에서 PowerShell을 시작한다. Harness는
`VsDevCmd.bat`를 자동 실행하지 않으므로 compiler/include/library 환경은 호출자에게서
상속된다. Ninja preset이면 같은 터미널에서 `ninja --version`도 확인한다.
## 3. Codex CLI 설치와 호환성 확인
[공식 Codex CLI 설치 안내](https://developers.openai.com/codex/cli)의 Windows 설치
방법으로 CLI를 설치한 뒤 새 터미널을 연다. npm 방식을 선택한 경우에는 먼저
[Node.js 공식 배포 페이지](https://nodejs.org/en/download)에서 Node.js/npm을 설치한다.
Harness는 Codex 앱 설치 여부와 별개로 `codex` 명령을 직접 실행한다.
```powershell
codex --version
codex login
codex login status
codex exec --help
```
`codex login`의 안내에 따라 인증한다. Harness 설정에는 계정이나 API 키를 넣지 않는다.
현재 실행기가 사용하는 옵션은 다음과 같다.
```text
codex exec --json --sandbox workspace-write --dangerously-bypass-hook-trust --cd <repository-root> -
```
`exec --help`에서 이 옵션들이 지원되는지 확인한다. 저장소는 최소 Codex 버전을
선언하지 않으므로 버전 숫자만으로 호환성을 판단하지 않는다. 문서 작성 시 로컬 CLI
`0.153.4`에서 옵션 목록은 확인했지만, 이것이 전체 실행 검증을 의미하지는 않는다.
실행기는 셸 alias나 PowerShell 함수 대신 Python 자식 프로세스로 Codex를 호출한다.
동일한 경로로 실행 가능한지 다음 명령으로 확인한다. 모델 호출은 발생하지 않는다.
```powershell
python -X utf8 -c "import subprocess; subprocess.run(['codex', '--version'], check=True)"
python -X utf8 -c "import subprocess; subprocess.run(['codex', 'exec', '--help'], check=True)"
```
터미널의 `codex`는 되는데 위 명령이 실패하면 `Get-Command codex -All`과
`where.exe codex`로 PATH를 확인한다. `.ps1` alias만 보이거나 npm shim이 자식
프로세스에서 실행되지 않으면 공식 Windows 설치 방식으로 CLI를 설치하고 실제
실행 파일 디렉터리를 PATH에 등록한 뒤 다시 점검한다.
## 4. 저장소 준비와 훅 확인
Git으로 저장소를 clone하거나, 기존 제품 저장소에 다음 Harness 구성요소를 가져온다.
기존 `AGENTS.md`와 훅 설정이 있으면 제품 규칙을 유지하면서 병합한다.
```text
AGENTS.md
.agents/skills/harness/SKILL.md
.agents/skills/review/SKILL.md
.codex/hooks.json
.harness/config.example.json
scripts/execute.py
scripts/hooks/
scripts/msvc_harness/
docs/HARNESS.md
docs/HARNESS_WORKFLOW.md
docs/ENVIRONMENT_SETUP.md
```
실행기와 훅이 경로를 기준으로 저장소를 찾으므로 위 배치를 유지한다. 제품 구현은
`src/`, 공개 header는 `include/`, 테스트는 `tests/`에 배치한다.
```powershell
git rev-parse --show-toplevel
git status --short
git config user.name
git config user.email
python -X utf8 scripts/execute.py --help
```
Git 작성자 정보가 없으면 대상 저장소에서 아래 예시를 자신의 정보로 바꾸어 설정한다.
실제 실행 전에는 준비한 설정·phase 파일을 검토하여 commit하고, 다른 작업의 변경이
없는 전용 checkout/worktree를 사용한다. 실행기는 `git add -A`와 자동 commit을 수행한다.
```powershell
git config --local user.name 'YOUR_NAME'
git config --local user.email 'YOUR_EMAIL'
```
저장소 루트에서 `codex`를 실행하고 `/hooks`에서 `.codex/hooks.json`의 `PreToolUse`와
`Stop`이 로드되는지 확인한다. 프로젝트 신뢰 설정과 훅의 실행 상태도 확인한다.
공식 훅 문서는 프로젝트 훅의 신뢰 요구사항과 Windows용 `commandWindows` 필드를
설명한다. [Codex 훅 문서](https://developers.openai.com/codex/hooks)
현재 실행기는 검토된 자동화용 `--dangerously-bypass-hook-trust`를 사용한다. 실행 전
저장소 훅 내용을 확인해야 하며, 이 옵션은 비활성 훅을 활성화하거나 빌드 설정을
대신하지 않는다. 사용자·관리자 설정에서 훅이 꺼져 있거나 프로젝트 훅이 제한되면
이를 먼저 해결한다.
Windows 훅은 `python -X utf8`과 Git 루트 탐색을 사용한다. 따라서 Codex가 실행하는
훅 환경에서도 Python과 Git이 보여야 한다. 아래 직접 호출은 훅 스크립트의 기본 실행만
확인하며, Codex가 훅을 자동 호출하는지까지 검증하지는 않는다.
```powershell
'{"tool_name":"Edit","tool_input":{"file_path":"docs/ENVIRONMENT_SETUP.md"}}' | python -X utf8 scripts/hooks/pre_tool_use.py
$LASTEXITCODE
```
통과 기준은 종료 코드 `0`이고 입력 해석 실패 메시지가 없는 것이다. C++ 편집에는
대응 테스트 파일이 먼저 필요하다. 기본 이름은 `{stem}_test.cpp`, `{stem}_tests.cpp`,
`test_{stem}.cpp`, `{stem}.test.cpp`이며 실제 실패 테스트 확인은 별도로 수행해야 한다.
## 5. 제품 빌드 설정
`.harness/config.example.json`은 모든 필드를 보여 주는 참고 자료다. `MyProject.sln`,
`windows-debug`, 테스트 실행 파일은 이 저장소에 존재하지 않으므로 그대로 복사해
완성된 설정으로 사용하지 않는다. 아래 방식 중 실제 프로젝트에 맞는 하나로
`.harness/config.json`을 작성한다. JSON은 **UTF-8 BOM 없이**, 주석 없이 저장한다.
PowerShell 7에서 텍스트를 저장할 때는 `Set-Content -Encoding utf8NoBOM`을 사용할 수 있다.
### A. CMake, preset 없이 사용
실제 루트 `CMakeLists.txt`가 있는 프로젝트의 최소 설정이다.
```json
{
"version": 1,
"projectType": "cmake",
"cmake": { "sourceDir": "." }
}
```
이 방식은 Harness가 `.harness/build`, `Debug`, `x64`를 사용한다. 프로젝트에 맞는
Visual Studio generator가 선택되는 환경에서 다음 순서로 확인한다. generator·구성·
toolset을 명확히 고정해야 하는 제품은 B 방식의 preset을 사용한다.
```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
```
각 명령이 성공해야 하고, 테스트 발견 JSON의 `tests` 배열에는 적어도 한 개의
테스트가 있어야 한다. 제품 CMake에서 C++ 언어와 테스트를 활성화하고 실제 테스트를
등록한다. Harness는 생성된 `CMakeCXXCompiler.cmake`의 compiler ID가 `MSVC`인지
확인하므로 MinGW/GCC 또는 Clang으로 설정된 build directory는 통과하지 않는다.
### B. CMake preset 사용
다음은 **이미 `windows-debug` configure/build/test preset이 정의된 제품**의 예시다.
실제 `CMakePresets.json` 또는 `CMakeUserPresets.json`의 이름과 binary directory로 바꾼다.
```json
{
"version": 1,
"projectType": "cmake",
"cmake": {
"sourceDir": ".",
"binaryDir": "out/build/windows-debug",
"configurePreset": "windows-debug",
"buildPreset": "windows-debug",
"testPreset": "windows-debug"
}
}
```
`binaryDir`, `configurePreset`, `buildPreset`, `testPreset`은 네 개를 함께 지정해야 한다.
`binaryDir`만 바꾸는 설정은 지원하지 않는다. 세 preset은 동일한 빌드 트리를 사용해야
하며 MSVC generator/toolset·아키텍처·빌드 구성을 제품 요구에 맞게 정의한다.
[CMake preset 공식 문서](https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html)
아래 명령은 설정의 `sourceDir`에서 실행한다. 이름은 실제 preset으로 바꾼다.
```powershell
cmake --list-presets
cmake --build --list-presets
ctest --list-presets
cmake --preset windows-debug
cmake --build --preset windows-debug
ctest --preset windows-debug --show-only=json-v1
ctest --preset windows-debug --output-on-failure
```
### C. Visual Studio solution/project와 MSBuild 사용
아래 파일명·출력 경로를 실제 `.sln` 또는 `.vcxproj`와 테스트 실행 파일로 바꾼다.
테스트 프레임워크는 지정하지 않으며, 실패할 때 nonzero로 종료하는 테스트 명령이 필요하다.
```json
{
"version": 1,
"projectType": "msbuild",
"msbuild": {
"solution": "MyProject.sln",
"configuration": "Debug",
"platform": "x64",
"testCommand": ["build/tests/Debug/MyProjectTests.exe"]
}
}
```
`testCommand`는 실행 파일과 인자를 분리한 문자열 배열이다. 명령 전체를 한 문자열로
넣거나 `&&`, 파이프, 셸 변수 확장을 기대하지 않는다. 작업 디렉터리는 저장소 루트다.
실행 파일에 경로를 쓰면 저장소 내부여야 하며, 파일명만 쓰면 PATH에서 찾는다.
```powershell
$msbuildExe = & $vswhere -latest -products '*' -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -find 'MSBuild\**\Bin\MSBuild.exe' | Select-Object -First 1
& $msbuildExe MyProject.sln /m /nologo /p:Configuration=Debug /p:Platform=x64
& ./build/tests/Debug/MyProjectTests.exe
```
빌드와 테스트 각각의 종료 코드가 `0`이어야 한다. 직접 MSBuild 방식에서 CTest 등록은
필수가 아니지만 `msbuild.testCommand`는 필수다. 현재 탐색기는 `.slnx`를 지원하지 않는다.
### 공통 설정 점검
`sourceDir`, `binaryDir`, `solution`, `tdd.testRoots`는 저장소 상대 경로로 지정하며
저장소 밖을 가리킬 수 없다. 알 수 없는 설정 필드는 오류다. `projectType: "auto"`는
루트 CMake metadata → 단일 루트 `.sln` → 단일 루트 `.vcxproj` 순서로 찾는다.
하위 디렉터리 제품이나 빌드 형식이 여러 개인 저장소는 `projectType`과 경로를 명시한다.
구문과 설정 형식을 빌드 없이 확인한다.
```powershell
python -X utf8 -m json.tool .harness/config.json
python -X utf8 -c "import sys; from pathlib import Path; sys.path.insert(0, 'scripts'); from msvc_harness.config import load_config; print(load_config(Path.cwd()))"
```
현재 `.gitignore`는 `.harness/build/`를 제외하지만 `.harness/config.json`,
`out/build/`, `.venv/`는 제외하지 않는다. 제품 저장소에서 공유할 설정과 로컬 파일·
빌드 산출물을 정하고 자동 staging 전에 필요한 ignore 규칙을 적용한다.
## 6. 구축 완료 확인과 최초 실행
제품 metadata와 설정을 준비한 뒤 Stop 훅 검증을 수동 실행한다. 실제 빌드·테스트와
빌드 산출물 작성이 발생한다.
```powershell
python -X utf8 scripts/hooks/stop_validation.py
```
이 스크립트는 **실패해도 프로세스 종료 코드가 0일 수 있다**. 표준 출력에
`"continue": false`와 `stopReason`이 나오면 검증 실패다. C++ 파일도 metadata도 없는
초기 저장소는 빌드를 수행하지 않고 조용히 종료하므로 MSVC 검증 성공으로 기록하지
않는다. `CODEX_STOP_VALIDATION_ACTIVE=1`이 설정된 재진입 환경이나 docs-only 실행
문맥에서도 검증이 생략될 수 있으므로 수동 점검은 일반 터미널에서 수행한다.
제품 검증 후 [실행 흐름](HARNESS_WORKFLOW.md)과
[Harness 스킬의 phase 형식](../.agents/skills/harness/SKILL.md)에 맞춰 실제 작업의
`phases/index.json`, `phases/<phase>/index.json`, `stepN.md`를 준비한다.
`context_files`에는 존재하는 파일만 넣는다. 현재 checkout에는 기존 문서가 참조하는
`docs/phase/README.md`도 없으므로 기록은 실행기가 명시한 다음 내용을 기준으로 준비한다.
- `docs/phase/<phase>/handoff.md`: 현재 상황, 결정과 이유, 미해결 문제, 검증 결과,
다음 시작점과 상세 기록 링크를 약 60줄로 유지한다.
- `docs/phase/<phase>/stepN.md`: 변경 파일, 결정, 검증, 실패한 접근과 이유를 기록한다.
- 실행 상태의 기준은 `phases/<phase>/index.json`이며 인계 기록은 상태를 대신하지 않는다.
`<phase>`를 실제 디렉터리 이름으로 바꾸어 실행한다.
```powershell
python -X utf8 scripts/execute.py <phase> --dry-run
python -X utf8 scripts/execute.py <phase>
```
`--dry-run`은 첫 pending step의 문맥 경로와 프롬프트 크기만 확인하며 Codex, Git 변경,
인증, 빌드·테스트는 실행하지 않는다. 실제 실행은 branch 전환, 파일 수정과 자동
commit을 수행한다. 원격 전송이 필요할 때만 `--push`를 사용한다.
구축 완료 기준은 다음과 같다.
- Python에서 `codex --version`과 `exec --help`를 직접 호출할 수 있고 인증이 되어 있다.
- Codex에서 프로젝트 훅이 로드되고 실제 도구 호출·종료 시 동작한다.
- 실제 제품의 MSVC build와 테스트가 성공하고 Stop 훅에서 차단 응답이 없다.
- 실제 phase의 dry-run에서 필요한 문맥을 읽고 첫 step 실행 결과와 index 상태가 일치한다.
Harness 자체를 수정하는 checkout에 Python 테스트가 있다면 별도로 아래를 실행한다.
현재 checkout에는 `tests/`가 없어 pytest 통과를 구축 완료 근거로 사용할 수 없다.
```powershell
python -m pip install pytest
python -m pytest -v -rs
python -m compileall -q scripts
```
## 7. 자주 발생하는 문제
| 증상 | 확인 및 조치 |
|---|---|
| `python` 또는 `codex`를 찾지 못함 | 새 터미널에서 PATH와 앱 실행 별칭을 확인한다. Python 자식 프로세스 점검까지 통과해야 한다. |
| `unexpected argument` / `unrecognized option` | `codex exec --help`로 실행기의 옵션 지원 여부를 확인하고 호환 CLI를 설치한다. |
| `not logged in` / 인증 실패 | Harness를 실행하는 동일 Windows 계정과 Codex 환경에서 다시 로그인한다. |
| 훅이 보이지 않거나 실행되지 않음 | `/hooks`, 프로젝트 신뢰, 사용자·관리자 훅 설정, `commandWindows` 지원과 자식 환경의 PATH를 확인한다. |
| `vswhere.exe` 또는 MSBuild를 찾지 못함 | Visual Studio Installer에서 C++ x64/x86 도구와 MSBuild를 설치·복구한다. 조회 결과가 빈 문자열인지도 확인한다. |
| CMake가 `-A x64`를 거부함 | 기본 generator가 Ninja 등인지 확인한다. Visual Studio generator 환경을 사용하거나 MSVC 개발 환경과 preset을 구성한다. |
| MSVC compiler metadata 오류 | 잘못된 compiler로 configure했는지, preset의 실제 binary directory와 `binaryDir`가 같은지 확인한다. |
| `CTest discovered no tests` | 제품 CMake의 테스트 활성화·등록, test preset과 구성 필터를 확인한다. 실행 파일 존재만으로는 충분하지 않다. |
| 여러 solution / build metadata 없음 | `projectType`과 실제 프로젝트 경로를 명시한다. C++ 파일만 복사한 상태로는 build를 검증할 수 없다. |
| `TDD GUARD` 차단 | 대응 테스트를 먼저 추가하고 red 단계 확인 후 제품 파일을 수정한다. |
| `dubious ownership` | 가능하면 현재 계정 소유의 checkout을 사용한다. 신뢰하는 공유 경로라면 해당 경로 하나만 Git `safe.directory`에 등록하고 자식 계정에서도 적용되는지 확인한다. |
| phase 또는 context 파일을 찾지 못함 | 현재 저장소에는 기본 phase가 없다. 실제 phase/index/step과 참조 파일을 먼저 작성한다. |
| 빌드·Codex 시간 초과 | Stop 검증 전체와 Codex 호출 각각의 제한은 1,800초다. 로그의 실패 단계와 도구 경로를 확인한다. |
운영 중 재시도, `error`/`blocked` 복구와 상태 기록은
[Harness 운영 가이드](HARNESS.md)와 [실행 흐름](HARNESS_WORKFLOW.md)을 참고한다.