- name
- harness
- description
- Codex용 프로젝트 하네스를 구축·마이그레이션·확장·점검하는 메타 스킬. `$harness` 또는 `$codex-harness:harness`를 명시적으로 호출하면 함께 요청한 조사·글쓰기·코드 작업이 일반적인 표현이어도 대상 프로젝트에 지속 가능한 하네스를 기본 구축·갱신한다. 명시 호출이 없는 일반 작업이나 개념 질문만으로 새 하네스를 만들지 않는다. 명시적인 읽기 전용·감사 요청은 그 범위를 따른다.
# Harness — Codex 에이전트와 스킬 설계
프로젝트에 맞는 역할, 실행 절차, 협업 계약을 생성하고 검증한다. 메인 세션이 오케스트레이터다. 에이전트는 역할을, 스킬은 재사용 절차를 정의한다.
## 호출 계약과 대상 프로젝트
- 사용자가 `$harness` 또는 `$codex-harness:harness`를 명시하면 하네스 구축·갱신을 기본 작업으로 해석한다. “이 주제로 조사해서 글을 써줘”처럼 동반 작업이 일반적인 요청이어도, 먼저 대상 프로젝트에 다시 사용할 수 있는 하네스를 구성하고 그 프로젝트에서 동반 작업을 수행한다. 빈 디렉터리도 대상이 될 수 있다. 사용자가 파일 쓰기를 금지하거나 감사·설명만 요청한 경우에는 그 제한을 따른다.
- 명시 호출이 없으면 하네스 자체의 구축·수정·점검을 요청한 경우에만 이 스킬을 적용한다. 일반 조사·글쓰기·코드 수정 또는 에이전트 개념 질문을 하네스 자동 구축 요청으로 바꾸지 않는다.
- 대상 프로젝트는 사용자가 지정한 프로젝트 경로이며, 지정하지 않았다면 현재 작업 디렉터리의 프로젝트다. 스킬이 설치된 플러그인 캐시나 이 스킬의 소스 저장소를 대상 프로젝트로 오인하지 않는다. 여러 프로젝트가 지정되면 각 프로젝트의 경계를 따로 확인한다.
- 생성하는 역할 정의는 항상 대상 프로젝트의 `.codex/agents/*.toml`에 둔다. 스킬·`AGENTS.md`·필요한 프로젝트 설정·`.harness/` 실행 기록과 `_workspace/communications/` 기록도 대상 프로젝트 아래에 둔다. 개인 범위 `~/.codex/agents/`나 플러그인 캐시에 프로젝트 역할을 만들지 않는다. 네이티브 에이전트 스레드는 파일이 아니며, 역할 TOML을 만드는 것과 스레드를 생성하는 것은 별도 단계다.
## 기본 원칙
- 프로젝트 에이전트는 대상 프로젝트의 `.codex/agents/<name>.toml`, 스킬은 `.agents/skills/<name>/SKILL.md`에 둔다. 개인 범위의 스킬 설치 요청이 별도로 있더라도 프로젝트 역할 정의와 실행 기록은 대상 프로젝트에 둔다.
- 작업에 필요한 프로젝트 로컬 역할 정의를 만들고 부모 세션의 실제 작업 디렉터리가 대상 프로젝트인지 확인한 뒤 작업용 네이티브 에이전트를 생성한다. 현재 `spawn_agent` 호출에는 `cwd` 인자가 없으므로 부모 세션이 다른 디렉터리에 있으면 도구별 `workdir`만 지정해도 자식의 프로젝트 루트를 보장할 수 없다. 이때 대상 프로젝트 파일은 명시적인 `workdir`로 구축하되 프로젝트 작업용 자식은 생성하지 않는다. 대상 프로젝트에서 새 Codex 세션을 시작한 뒤 역할 발견과 실행을 다시 확인한다. 역할 파일 생성 직후 현재 세션이 새 역할을 발견한다고 가정하지 않는다. 부모 세션이 대상 프로젝트에 있지만 새 역할이 노출되지 않았다면 정의를 읽어 빌트인 역할에 지시하는 대체 실행을 명시하고, 실제 사용한 역할을 보고한다.
- 현재 노출된 서브에이전트 도구와 스키마를 먼저 확인하고 [실행 가이드의 네이티브 실행 사전 점검](references/runtime-guide.md#네이티브-실행-사전-점검)을 따른다. 도구 노출이나 정적 검증만으로 실행 가능하다고 판단하지 않는다. 첫 대기 자식의 실제 ID가 반환된 뒤 팬아웃하며, 성공한 자식을 첫 작업에 재사용한다.
- 독립적으로 완료 가능한 작업을 병렬화한다. 첫 생성 확인 후 유용한 자식 작업 2~3개로 넓히고 실제 동시 실행 한도에 맞춘다. 도구가 없거나 부모 스레드 오류로 ID 없이 실패하면 추가 생성을 멈추고 메인 세션에서 같은 실질 작업을 순차 수행한다. 네이티브 실행의 미완료 상태와 한계는 별도로 기록한다.
- 메인이 의존성, 파일 소유권, 공용 설정, 에이전트 수명, 통합, 완료 판정을 소유한다. 워커에게 배타적인 수정 범위를 주고 다른 작업자의 변경을 되돌리지 않도록 명시한다.
- 동료에게 영향을 주는 발견·질문·차단 사유·인계를 적극적으로 전달하고 신속히 답한다. 중요한 메시지는 `_workspace/communications/`에 기록한다. 네이티브 전송과 로컬 기록은 별도 동작이며 메인이 계약·소유권 변경을 확정한다.
- 모델·추론 수준은 부모 설정을 상속한다. 명시적인 요구가 없는 한 특정 모델을 고정하지 않는다. 전역 설정을 변경하지 않는다.
- 사용자 요청으로 이미 허용된 가역적 작업은 계속 진행한다. 습관적인 계획 승인이나 완료 후 피드백 대기를 추가하지 않는다.
## 프로젝트 로컬 부트스트랩
명시 호출로 구축·갱신할 때는 Phase 0에서 기존 파일을 조사한 뒤, 동반 작업을 시작하기 전에 다음을 대상 프로젝트에서 수행한다. 이미 설치되어 있으면 차이만 갱신하고 기존 사용자 내용·모델·권한 설정을 보존한다.
1. 실제 소스 형태를 확인한다. 저장소 체크아웃에 `scripts/install.py`가 **실제로 있으면** 그 설치기를 대상 프로젝트 경로의 `--target`으로 사용할 수 있다. 플러그인만 설치된 환경에는 저장소 루트 설치기가 있다고 가정하지 않는다.
2. 설치기가 없으면 현재 로드된 `harness` 스킬 번들의 파일을 대상 프로젝트 `.agents/skills/harness/`에 프로젝트 로컬 사본으로 두고, 필요한 역할을 Phase 3 절차로 대상 프로젝트 `.codex/agents/`에 만든다. `AGENTS.md`의 하네스 포인터와 필요한 프로젝트 설정을 기존 내용에 안전하게 병합한다. 기존 파일과 충돌하면 무조건 덮어쓰지 말고 차이를 확인해 보존한다. 플러그인 캐시·개인 설정에 결과를 기록하지 않는다.
3. 대상 프로젝트에서 실제 재사용할 역할·스킬·오케스트레이터 연결을 완성하고 구조를 검증한다. 동반 작업의 산출물도 대상 프로젝트 안에 둔다. 하네스 파일을 만든 것만으로 네이티브 역할이 현재 세션에 로드되었거나 작업에 성공했다고 보고하지 않는다.
대상 프로젝트의 `.agents/skills/` 또는 `.codex/agents/` 쓰기가 활성 샌드박스에서 `Operation not permitted` 등으로 거부되면 실패한 경로와 원문 오류를 보고하고 하네스 구축을 미완료로 둔다. 필요한 스킬·역할 정의를 `.harness/`, 플러그인 캐시 또는 개인 범위에 대신 쓰지 않는다. 권한 모드나 사용자의 기존 권한 선호를 임의로 바꾸지 않는다.
## Phase 0: 현황 감사
1. 대상 프로젝트 루트와 실행 위치를 확인한 뒤 그 아래의 `AGENTS.md`, `.codex/config.toml`, `.codex/agents/`, `.agents/skills/`, 기존 실행 기록을 확인한다. 마이그레이션이면 기존 하네스도 읽어 보존할 동작을 추출한다.
2. 실제 파일, 스킬의 참조, `AGENTS.md` 포인터를 대조해 누락·중복·오래된 연결을 찾는다. 사용자의 기존 편집을 보존한다.
3. 명시 호출의 신규 구축·갱신은 위 프로젝트 로컬 부트스트랩과 Phase 1부터 수행한다. 역할 추가는 Phase 2·3·5·6, 스킬 수정은 Phase 4·6과 영향받는 통합 부분, 구조 변경은 Phase 2부터 영향 범위만 수행한다. 점검·동기화는 Phase 7을 따른다.
4. 발견한 불일치와 진행 범위를 짧게 알리고 허용된 작업을 실행한다. 결과를 좌우하는 필수 입력만 확인한다.
## Phase 1: 도메인 분석
1. 목표, 입력, 최종 산출물, 완료 기준, 기존 제약을 정리한다. 코드베이스면 스택·모듈·테스트 명령과 공용 경계면을 파악한다.
2. 반복 작업과 일회성 작업을 구분한다. 기존 에이전트·스킬이 충분하면 재사용한다.
3. 설명 수준은 사용자 맥락에 맞춘다. 불확실한 환경 사실은 실제 파일·도구·공식 문서로 확인한다.
## Phase 2: 팀 아키텍처 설계
[에이전트 설계 패턴](references/agent-design-patterns.md)을 읽고 다음 여섯 패턴 중 적절한 조합을 선택한다.
| 패턴 | 실행 기준 |
| --- | --- |
| 파이프라인 | 앞 단계의 승인된 산출물 이후 다음 작업 실행 |
| 팬아웃/팬인 | 독립 작업 병렬 수행 후 메인이 통합 |
| 전문가 풀 | 필요한 전문 역할만 선택 호출 |
| 생성-검증 | 구현 완료 구간을 독립 리뷰·QA하고 제한된 수정 반복 |
| 감독자 | 메인이 남은 작업과 여유 슬롯을 보고 동적 배분 |
| 계층적 위임 | 도메인은 계층적으로 나누되 실행은 메인 중심으로 평탄화 |
각 작업에 프로젝트 루트, 변하지 않는 입력·지문, 확정된 결정, 필요한 스킬 경로, 의존성, 담당 역할, 쓰기 허용 경로, 산출물, 검증 방법, 재시도 한도를 정한다. 독립 작업에는 작은 완결된 패킷을 주고 같은 주제를 재사용할 때도 변경된 입력을 다시 읽게 한다. 전체 대화 상속이나 특정 fork 옵션을 가정하지 않는다. 기본적으로 자식은 재귀적으로 위임하지 않고 추가 분할안을 메인에게 반환한다. 같은 파일을 수정하는 작업은 순차화하거나 메인이 통합한다.
## Phase 3: 에이전트 정의 생성
1. 기존 역할과 비교한다. 포함 관계면 재사용하고, 안정적인 전문 책임이 추가될 때만 커스텀 에이전트를 생성한다. 단발성 탐색은 현재 런타임의 빌트인 역할로 충분할 수 있다.
2. 기본 역할 `harness_explorer`, `harness_architect`, `harness_worker`, `harness_reviewer`, `harness_qa` 중 필요한 것만 호출한다. 역할 파일 수와 동시 실행 수는 다르다.
3. 대상 프로젝트의 `.codex/agents/<name>.toml`에 `name`, `description`, `developer_instructions`를 작성한다. 지시문에 책임, 입력·출력 계약, 소유권, 협업, 오류·후속 작업 처리를 넣는다. 작업용 에이전트를 생성하기 전에 이 정의를 먼저 만든다.
4. 읽기 전용 탐색·리뷰와 실행 QA를 구분한다. QA는 테스트 캐시·임시 산출물 때문에 `workspace-write`가 필요할 수 있다. 제품 코드 수정은 워커가 담당하고 QA는 재검증한다. QA 역할에 제품 수정을 겸하게 하지 않는다.
반복 생성에는 대상 프로젝트에 복사한 이 스킬의 `scripts/create_agent.py`를 사용한다. 아래 명령은 대상 프로젝트 루트에서 실행하는 예다. 지시문 입력 파일은 대상 프로젝트 안에 준비한다.
```bash
python3 .agents/skills/harness/scripts/create_agent.py \
--target . --name domain_worker \
--description '도메인 변환 규칙을 구현하는 워커' \
--instructions-file .harness/domain-worker-instructions.md \
--sandbox-mode workspace-write
```
역할 템플릿과 재사용 기준은 [설계 패턴](references/agent-design-patterns.md), 적용 예는 [팀 예시](references/team-examples.md)를 참조한다.
## Phase 4: 스킬 생성
1. [스킬 작성 가이드](references/skill-writing-guide.md)를 읽는다. 기존 기능과 중복되는 스킬을 새 이름으로 복제하지 않는다.
2. `.agents/skills/<lowercase-hyphen-name>/SKILL.md`를 만들고 frontmatter에는 `name`, `description`만 둔다. description에 구체적 작업, 시작·후속 트리거, 인접 작업과의 경계를 쓴다.
3. 본문은 핵심 절차를 500줄 이내로 유지한다. `references/`에는 선택적으로 읽을 상세 정보, `scripts/`에는 실제 반복되는 결정적 작업, `assets/`에는 산출물 템플릿을 둔다.
4. 메타데이터 → 본문 → 필요한 참조 순서로 정보를 읽도록 연결한다. 각 링크에 읽어야 하는 시점을 쓴다.
5. 역할 지시 또는 위임 프롬프트에 필요한 스킬 경로와 읽을 부분을 명시한다. 자식에게 스킬이 자동 로딩된다고 가정하지 않는다. 별도 Skill 호출 도구를 가정하지 않는다.
## Phase 5: 통합 및 오케스트레이션
[오케스트레이터 템플릿](references/orchestrator-template.md)을 바탕으로 도메인 오케스트레이터를 구성한다. 실제 초기화·결과 등록·재사용·통신 기록에는 [실행 가이드](references/runtime-guide.md)의 CLI와 네이티브 도구 경계를 따른다.
1. 메인이 `run.py init`으로 `.harness/runs/<run-id>/plan.json`과 작업별 `input.md`를 만든다. v2 계획은 프로젝트 루트, 입력·계약 지문, 결정·스킬 경로를 기록한다. 수정 대상은 `ownership`, 변하지 않는 계약·참조는 `inputs`에 두며 선행 산출물은 `dependencies`로 전달한다.
2. 의존성이 충족된 작업만 실행한다. 부모 세션의 실제 `cwd`가 대상 프로젝트와 같고 필요한 프로젝트 역할 정의가 생성됐는지 먼저 확인한다. 다른 `cwd`라면 `spawn_agent`의 `cwd` 부재를 도구별 `workdir`로 우회하지 않고 프로젝트 작업용 대기 자식도 생성하지 않는다. 대상 프로젝트에서 새 세션을 시작할 때까지 네이티브 실행을 미실행으로 남긴다. 같은 `cwd`에서 실행할 때에도 각 작업 도구의 `workdir`와 패킷의 절대 프로젝트 루트를 대상 프로젝트로 지정하고, 새 역할의 현재 세션 발견 여부를 확인한다. 첫 대기 자식의 실제 생성 결과로 네이티브 실행을 점검하고 성공한 자식을 등록한 뒤 병렬 작업을 늘리고 최신 패킷을 배정한다. 부모 스레드를 찾지 못하면 역할별 재시도나 가짜 ID 등록 없이 순차 대체 절차를 따른다. 메인은 자식이 실행하는 동안 공용 계약·통합 준비 등 독립 작업을 수행한다.
3. `run.py result`로 실제 결과를 등록하고 작업 상태와 네이티브 세션 상태를 구분한다. 메인은 실제 유휴·중단 응답을 확인한 뒤 레지스트리를 갱신하며, 이전 작성자의 중단·유휴 확인 전에는 쓰기 소유권을 재배정하지 않는다. 로컬 상태 변경은 에이전트를 멈추거나 슬롯을 반환하지 않는다.
4. 중요한 발견, 구체적인 질문·답변, 계약 제안, 입력 준비, 차단 사유, 의미 있는 이정표와 인계를 적극적으로 전달한다. 쓰기 가능한 역할은 `communication.py log`로 발신 내용을 먼저 기록한 뒤 실제 도구로 보내고 전송 결과를 별도 연결한다. 읽기 전용 역할은 메인에게 기록·전달을 요청한다. 동료 토론 후 계약·소유권 확정은 메인이 한다.
5. 실패 원인을 확인하고 일시적인 작업 오류는 기본 1회 추가 시도 또는 제한된 재할당을 수행한다. 네이티브 실행 사전 점검의 부모 스레드 오류에는 이 역할별 재시도를 적용하지 않는다. 필수 작업 실패는 하네스 완료를 막는다. 선택적 작업 생략은 영향과 사유를 기록한다.
6. 모듈 경계가 준비되는 즉시 QA를 수행하고 통합 후 최종 검증한다. 같은 캐시를 쓰는 테스트·빌드는 충돌을 피하도록 순차 실행한다.
7. `AGENTS.md`에는 도메인 관리 마커 안에 목표와 오케스트레이터 포인터만 추가한다. 설치기가 관리하는 `codex-harness:start/end` 부트스트랩 블록과 도메인 블록을 구분하여 재설치해도 도메인 연결이 유지되게 한다. 기존 내용은 보존하고 긴 실행 규칙·역할 목록은 복제하지 않는다.
```markdown
<!-- codex-harness:domain:start -->
## 프로젝트 하네스
{도메인} 작업의 생성·수정·부분 재실행에는 `.agents/skills/{domain}-orchestrator/SKILL.md`를 읽는다.
하네스 자체의 구축·점검·동기화에는 `.agents/skills/harness/SKILL.md`를 읽는다.
<!-- codex-harness:domain:end -->
```
후속 요청은 `run.py resume`으로 새 실행을 만든다. 변경된 입력·계약·결과와 하위 의존성이 무효화되면 해당 작업을 다시 실행한다. 재사용 에이전트도 갱신된 패킷을 읽으며 과거 실행을 덮어쓰지 않는다.
## Phase 6: 검증 및 테스트
1. 대상 프로젝트 루트에서 `python3 .agents/skills/harness/scripts/validate.py --project .`를 실행한다. 이 명령은 구조를 검사하며 실제 에이전트 실행 성공을 증명하지 않는다.
2. 에이전트 TOML, 스킬 frontmatter, 참조 경로, 포인터, 소유권 중복, 의존성 순환을 확인한다. 실행 완료 전에는 `validate.py --project . --run <run-id> --complete`로 필수 결과·산출물·검사 근거·최신성을 확인한다.
3. [QA 가이드](references/qa-agent-guide.md)에 따라 생산자와 소비자 양쪽을 비교한다. 테스트·리뷰 결과는 통과/실패/미실행으로 구분한다.
4. [스킬 테스트 가이드](references/skill-testing-guide.md)에 따라 현실적인 정상·오류·부분 재실행 사례를 검증한다. 네이티브 실행 사전 점검이 성공하면 서로 다른 파일을 맡은 워커와 독립 검증의 작은 실제 실행을 수행한다. 네이티브 실행을 검증하는 스모크 테스트는 순차 대체 작업으로 통과 처리하지 않는다.
5. 문제를 수정한 후 영향받는 검사를 다시 실행한다. QA 수정은 기본 최대 2회 반복하며, 한도 이후에도 필수 실패는 실패로 남긴다. 실행하지 않은 테스트를 통과로 보고하지 않는다.
## Phase 7: 진화·운영·유지보수
1. 실제 역할·스킬 파일과 오케스트레이터·포인터를 대조해 drift 목록을 만든다. 변경 이유와 대상은 실행 기록에 남긴다.
2. 결과 품질 문제는 해당 스킬, 역할 문제는 에이전트, 순서·통신 문제는 오케스트레이터, 트리거 누락은 description을 수정한다.
3. 요청된 변경을 작은 단위로 적용하고 참조·포인터를 함께 동기화한다. 역할 병합·삭제는 호출부의 영향까지 확인한다.
4. 구조 변경은 실행 사례까지, 국소 문서 변경은 구조·참조 중심으로 검증한다. 반복 실패에서 발견한 일반적인 개선은 범위 내에서 반영한다.
5. 최종 보고에 변경 파일, 실제 실행한 검사와 결과, 남은 제한을 적는다. 피드백이 없음을 승인이나 테스트 통과로 해석하지 않는다.
## 완료 조건
- 필요한 역할·스킬·오케스트레이터와 `AGENTS.md` 포인터가 일치한다.
- 실제 런타임에 맞는 도구 사용, 입력 갱신, 독립 소유권, 세션 수명, 의존성, 재시도, 부분 재실행 계약이 있다.
- 중요한 협업 사건과 실제 전송·응답이 상관 ID로 연결되며 미기록·미전송 범위는 명시된다.
- 필수 작업과 검사에 미해결 실패가 없고 미실행 검사는 명시되어 있다.
- 기존 프로젝트 파일과 전역 설정을 불필요하게 변경하지 않았다.
Auf GitHub ansehen