modify harness framework
This commit is contained in:
@@ -0,0 +1,171 @@
|
||||
# Harness 실행 흐름
|
||||
|
||||
Harness는 승인된 phase를 독립 Codex 세션으로 실행하고 C#·.NET 8 제품 규칙을
|
||||
검증한다. 설정 예시는 [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`가 있어도 성공으로 처리하지 않는다.
|
||||
Stop 실패가 exit code 0으로 끝나는 경우도 있으므로 완료 보고 직후 executor가 제품을
|
||||
다시 검증한다. 실패하면 성공 상태를 취소하고 같은 최대 3회 호출 예산에서 재시도한다.
|
||||
독립 검증에도 실제 docs-only 판정과 별도의 총 1,800초 검증 제한을 적용한다.
|
||||
|
||||
## 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 파괴 명령을 차단한다.
|
||||
Windows 셸의 종료 코드 변환에 의존하지 않도록 JSON `permissionDecision: "deny"`로
|
||||
거부한다. 실제 Codex 편집 payload의 `tool_input.command`에서 patch 경로를 읽는다.
|
||||
C# 제품 `.cs` 편집에는 대응 테스트 파일 존재 여부를 검사한다. 기본 루트는
|
||||
저장소 `tests/`이며 편집 파일 옆 `tests/`, `test/`도 대응 테스트를 찾는다.
|
||||
`Foo.cs`의 대응 이름은 `FooTests.cs` 또는 `FooTest.cs`다.
|
||||
테스트 루트의 보조 코드, 중첩 `bin/`·`obj/` 등 산출물, 외부 의존성·명시 generated
|
||||
경로는 제외한다. `Program.cs`나 `.Designer.cs`라는 이름만으로 면제하지 않는다.
|
||||
필요한 면제는 정확한 `tdd.exclude` 경로와 이유를 기록한다. 이 설정은 제품 존재
|
||||
탐색을 우회하지 않는다. 테스트 파일 존재와 실제 red-green 증거를 구분한다.
|
||||
|
||||
`tdd.testPatterns`는 `{stem}`을 포함하는 C# 파일명 패턴이다. 경로 구분자는 허용하지
|
||||
않으며 테스트 위치는 `testRoots`로 지정한다. 한 검사 호출 안에서 후보 목록을 재사용하고
|
||||
다음 호출에는 파일 추가·삭제를 반영한다. 제품 탐색에서 제외한 산출물·fixture 경로의
|
||||
파일을 대응 테스트 증거로 사용하지 않는다.
|
||||
|
||||
## 8. 종료 전 검증
|
||||
|
||||
`validation` 생략 또는 `full`이면 Stop 훅이 발견한 C# 제품 전체를 검증한다.
|
||||
|
||||
- 저장소 루트 `global.json`에 따른 .NET 8 SDK 선택 확인
|
||||
- target의 실제 각 프로젝트와 모든 test project의 `TargetFramework`/`TargetFrameworks`를
|
||||
SDK로 평가해 .NET 8인지 확인; 상속된 props·속성 및 ProjectReference 그래프도 평가하며 빈 값·비지원 TFM·저장소 밖 참조는 거부
|
||||
- version 2 설정의 target과 명시된 모든 `testProjects`를 restore/build;
|
||||
build 경고는 오류로 처리하고 solution에 빠진 test project도 직접 build
|
||||
- 각 test project를 VSTest로 실행하고 현재 호출의 고유 디렉터리에 생성된 모든 TRX 검사
|
||||
- 실행 0건·skip-only·누락·손상·실패 TRX는 실패; 과거 결과를 성공 근거로 사용하지 않음
|
||||
- 지원 metadata 없음: 제외되지 않은 C# 소스가 있으면 orphan 오류
|
||||
- 제품과 metadata 모두 없음: 제품 검증 대상 없음; 제품 build 성공으로 기록하지 않음
|
||||
|
||||
전체 검증은 1,800초 deadline을 공유하며 SDK·TFM 평가·restore·build·test 중 실패한 단계에서
|
||||
중단한다. `tests/fixtures/`는 제품 자동 탐색에서 제외하는 도구 검증용이다.
|
||||
Stop 프로세스 종료 코드만으로 통과를 판정하지 않는다. `continue: false`와
|
||||
`stopReason` 응답은 검증 실패이며 실제 자동 훅 호출은 별도로 확인한다.
|
||||
|
||||
`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 상태를 우선한다. 이 저장소의 fixture
|
||||
검증은 제품 요구사항이나 실제 제품 build 완료를 의미하지 않는다. 실행한 명령과
|
||||
결과, SDK·테스트 건수와 남은 미검증 항목은 해당 phase 기록에서 확인한다.
|
||||
Reference in New Issue
Block a user