157 lines
6.8 KiB
Markdown
157 lines
6.8 KiB
Markdown
# Harness 실행 흐름
|
|
|
|
Harness는 승인된 phase를 독립 Codex 세션으로 실행하고 MSVC C++ 제품 규칙을
|
|
검증한다. 설정 예시는 [HARNESS.md](HARNESS.md), phase 기록 형식은
|
|
[phase README](phase/README.md)를 참고한다.
|
|
|
|
## 1. 계획
|
|
|
|
`AGENTS.md`와 변경에 관련된 제품 문서·코드·테스트를 확인하고 작업을 한 가지 책임의
|
|
step으로 나눈다. 각 step은 목표와 범위, 관련 파일, 핵심 제약, 실제 Acceptance
|
|
Criteria를 가진다. 공개 계약이 필요한 경우에만 시그니처를 적는다. 이전 대화에
|
|
의존하지 않으며 문서 전체를 step 본문에 복사하지 않는다.
|
|
|
|
제품 기능의 red-green 작업은 한 step 안에서 끝낸다.
|
|
|
|
```text
|
|
실패 테스트 작성·확인 → 최소 구현 → 전체 관련 테스트 성공 → step 종료
|
|
```
|
|
|
|
## 2. Phase 파일
|
|
|
|
```text
|
|
phases/
|
|
index.json
|
|
<phase>/
|
|
index.json
|
|
step0.md
|
|
docs/phase/<phase>/
|
|
handoff.md
|
|
step0.md
|
|
```
|
|
|
|
`phases/{phase}/index.json`이 실행 상태의 기준이다. `context_files`는 기존 참고 문서,
|
|
`validation`은 `full` 또는 `docs-only`를 선택한다.
|
|
|
|
```json
|
|
{
|
|
"project": "<제품명 또는 미정>",
|
|
"phase": "add-parser",
|
|
"steps": [
|
|
{
|
|
"step": 0,
|
|
"name": "implement-parser",
|
|
"status": "pending",
|
|
"context_files": ["docs/ARCHITECTURE.md"],
|
|
"validation": "full"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
## 3. 읽기 전용 확인
|
|
|
|
```powershell
|
|
python scripts/execute.py <phase> --dry-run
|
|
```
|
|
|
|
첫 pending step의 현재 주입 경로, 경로별 문자 수와 전체 프롬프트 문자 수를
|
|
출력한다. Codex, Git, timestamp와 파일을 변경하지 않는다. `--push`와 동시 사용은
|
|
오류다.
|
|
|
|
## 4. 프롬프트 구성
|
|
|
|
각 호출 직전에 index, `context_files`와 handoff를 다시 읽고 다음 순서로 한 번만
|
|
결합한다.
|
|
|
|
```text
|
|
AGENTS.md
|
|
→ 공통 작업 규칙
|
|
→ context_files
|
|
→ 현재 phase handoff 또는 호환 summary
|
|
→ 직전 실패 요약
|
|
→ 현재 step
|
|
```
|
|
|
|
`context_files` 생략은 추가 문서 없음이다. 잘못된 배열, 없는 파일, UTF-8로 읽을 수
|
|
없는 파일, 절대 경로, 저장소 밖 경로와 외부를 가리키는 symlink/junction은 Codex나 Git 변경 전에
|
|
거부한다. 경로 표기와 대소문자만 다른 중복도 한 번만 넣는다.
|
|
|
|
handoff가 없을 때만 현재 step보다 앞선 완료 step 중 가장 최근 하나의 summary를
|
|
최대 1,000자로 전달한다. 이후 step이나 모든 과거 summary를 누적하지 않는다.
|
|
|
|
## 5. 실행과 상태
|
|
|
|
Executor는 `feat-{phase}` branch에서 각 pending step을 독립 `codex exec` 프로세스로
|
|
실행한다. Codex는 종료 전에 현재 `docs/phase/{phase}/stepN.md`, handoff와 phase index를
|
|
갱신한다.
|
|
|
|
| 상태 | 의미 |
|
|
|---|---|
|
|
| `completed` | exit code 0일 때만 성공, executor가 timestamp와 commit 처리 |
|
|
| `error` | 자동 시도 예산 소진, 이유와 timestamp 기록 후 중단 |
|
|
| `blocked` | 사용자 또는 외부 환경 조치 필요, 추가 호출 없이 중단 |
|
|
|
|
프로세스가 nonzero로 끝나면 index에 `completed`가 있어도 성공으로 처리하지 않는다.
|
|
|
|
## 6. 재시도와 로그
|
|
|
|
Executor의 호출 예산은 최초 호출을 포함해 총 3회다. 한 Codex 세션 안의 일반적인
|
|
red-green 수정 횟수를 별도로 3회로 제한하지 않는다.
|
|
|
|
재시도 입력의 오류 본문은 총 4,000자로 제한한다. 앞 1,500자와 끝부분 최대 2,500자를
|
|
남기고 중간 생략 marker를 제한 안에 포함한다. 전체 stdout/stderr 결과는
|
|
`phases/{phase}/stepN-output.json`에 저장하지만 다음 시도에서 같은 파일을 덮어쓴다.
|
|
장기 보관할 시행착오는 step 기록에 요약한다. timeout도 같은 호출 예산의 실패이며
|
|
인증·CLI 옵션 같은 환경 오류는 즉시 중단한다.
|
|
|
|
## 7. 편집 전 정책
|
|
|
|
PreToolUse 훅은 위험한 삭제, 강제 push, hard reset과 SQL 파괴 명령을 차단한다.
|
|
C/C++ 소스·header 편집에는 대응 테스트 파일 존재 여부를 검사한다. 테스트 파일,
|
|
`main.cpp`, build output, 외부 의존성, generated 경로와 설정된 제외 패턴에는 기존
|
|
면제 규칙을 적용한다.
|
|
|
|
기본 basename 테스트 패턴은 같은 검사 호출 안에서 test root별 목록을 재사용한다.
|
|
경로를 포함한 복합 패턴은 링크·상대 경로 호환성을 위해 기존 rglob을 사용하므로 패턴별
|
|
순회가 발생할 수 있다. C++ 파일 탐색은
|
|
제외 디렉터리의 불필요한 방문을 줄인다. 다음 호출에는 파일 추가·삭제가 즉시 반영된다.
|
|
C++ 파일 탐색은 제외 폴더 내부의 symlink/junction도 건너뛴다. 기존에는 이 링크를 통해
|
|
비제외 소스나 중복 경로를 찾을 수 있었으나 이제는 제외 폴더의 링크로만 접근 가능한
|
|
소스를 자동 감지하지 않는다. 실제 제품 source 경로와 build metadata를 지정한다.
|
|
그 외 대응 테스트 및 프로젝트 판정은 유지하며 실제 시간 개선율은 별도 측정 전까지
|
|
미검증이다.
|
|
|
|
## 8. 종료 전 검증
|
|
|
|
`validation` 생략 또는 `full`이면 Stop 훅이 발견한 C++ 제품 전체를 검증한다.
|
|
|
|
- CMake: configure, build, CTest 발견, CTest 실행과 MSVC compiler metadata 확인
|
|
- MSBuild: build 후 `.harness/config.json`의 `msbuild.testCommand` 실행
|
|
- metadata 없음: 제외되지 않은 C++ 파일이 하나라도 있으면 orphan 오류
|
|
|
|
`docs-only`이면 executor가 현재 phase를 자식 프로세스 환경으로 전달하고 Stop 훅이
|
|
실제 Git 변경을 다시 검사한다. 루트 `AGENTS.md`, `docs/**/*.md`, 현재 phase의
|
|
`index.json`과 `stepN-output.json`만 허용하며 실제 문서 변경이 있어야 생략한다.
|
|
rename은 원래 경로와 새 경로를 모두 검사한다. Git 실패, 빈 변경, bookkeeping만 있는
|
|
변경, untracked C++ 또는 다른 파일이 하나라도 있으면 전체 검증으로 돌아간다.
|
|
symlink나 junction으로 해석되는 변경 경로도 보수적으로 전체 검증한다.
|
|
|
|
## 9. Commit, 완료와 재개
|
|
|
|
step 성공 시 executor는 제품 변경과 metadata를 분리해 commit한다. 모든 step이
|
|
성공하면 phase와 top-level 상태를 `completed`로 바꾸고 `--push`가 있으면
|
|
`origin/feat-{phase}`에 push한다. 실행기는 광범위한 staging을 할 수 있으므로 깨끗한
|
|
전용 worktree에서 실행한다.
|
|
|
|
재개 절차:
|
|
|
|
1. `error` 또는 `blocked` 원인을 해결한다.
|
|
2. 해당 step status를 `pending`으로 바꾼다.
|
|
3. `error_message`/`failed_at` 또는 `blocked_reason`/`blocked_at`을 제거한다.
|
|
4. handoff, 직전 원본 출력과 index를 확인한 뒤 다시 실행한다.
|
|
|
|
강제 종료로 handoff가 낡았을 수 있으므로 index 상태를 우선한다. 이 저장소에는 아직
|
|
실제 C++ 제품 소스와 확정된 build 설정이 없어 일반 제품 MSVC build 성공은
|
|
검증되지 않았다.
|