start-harness.sh라는 시작 명령 한 줄로 켜지는 '하네스(harness)' 시스템을 처음부터 끝까지 뜯어봅니다. 하네스란, AI가 스스로 코드를 고치고 "다 됐다"고 말할 때 정말 됐는지 증거로 검사해 통과 못 하면 막아 주는 자동 감시·실행 장치입니다. 이 시스템은 스스로 실수를 찾아 규칙과 코드를 고쳐 나가며, Codex(오픈AI의 코딩 AI) 위에서 돌아갑니다. 여기에, 원래 Claude Code(앤트로픽의 코딩 AI 도구)에서 쓰던 핵심 명령 네 가지 /team · /init-project · /qa-cycle · /qa-scenario-gen이 Codex 환경으로 옮겨지면서 무엇이 어떻게 달라졌는지 나란히 비교합니다.
loop-era-supervisor.py라는 지휘 프로그램 안의 PHASE_ORDER라는 목록이 15단계의 실행 순서를 정해 둡니다. 이 시스템이 잘 돌아가는지 재는 잣대는 l6_blocker_count인데, 이건 "아직 남은 치명적 문제(blocker)의 개수"이고 0이 목표입니다. 각 단계의 결과는 phase_history라는 기록에 차곡차곡 쌓이고, 마지막에는 results.tsv에 "살림(keep)"인지 "버림(discard)"인지로 남습니다.
이 시스템의 두 번째 버전(v2)에서 qa_scenario_gen이라는 단계가 두 번째 자리에 새로 끼면서, 원래 14단계였던 흐름이 → 15단계로 늘었습니다.
app_candidates / service_candidates / database_hints 즉 화면·서비스·데이터베이스의 흔적을 찾아내고, 그에 맞춰 어떤 검사를 꼭 해야 할지를 자동으로 정합니다.project-profile.json이라는 프로필 파일을 읽어, 7가지 QA 검사(시나리오) 중 무엇을 해야 하는지 자동으로 고릅니다. 화면(UI)·서버 통신(API)·데이터베이스(DB)·브라우저 콘솔 오류 이렇게 4가지 축으로 나눠, "꼭 필요함"으로 표시된 검사만 실행 목록에 넣습니다. 각 검사는 통과했다는 증거를 정해진 형식(evidence contract, 증거 계약)으로 반드시 남겨야 합니다.blocker_total=0이면(남은 문제가 없으면) status: "skip" 을 돌려주고 이 단계를 건너뜁니다. 문제가 있으면 가장 급한 경로부터, 그리고 검증·반박 리뷰·확인용 일꾼을 만들어 붙입니다.qa-scenarios.json에 적힌 검사별 명령을 실행하고, 통과 증거(evidence contract)가 규격대로 나왔는지 검증합니다. 실패는 종류별 이름표(failure_labels)로 분류합니다.
qa-scenario-gen.py는 위 흐름의 2단계에서 따로 실행되는 파이썬 프로그램입니다. 하는 일은 "무엇을 검사할지"를 자동으로 정하는 것입니다.
project-profile.json이라는 프로필 파일에서 app_candidates, service_candidates, database_hints, 즉 화면·서비스·데이터베이스의 흔적을 읽어, 7가지 검사(시나리오) 각각이 required 즉 "꼭 필요한지"를 자동으로 정하고, qa-scenarios.json이라는 검사 목록 파일을 만들어 냅니다.
그다음 qa-cycle-runtime.py안의 scenario_checks()라는 함수가 이 목록 파일을 읽어 각 검사 명령을 실제로 돌리고, 통과 증거(evidence contract, JSON으로 출력)가 규격대로 나왔는지 확인합니다.
app_candidates → 화면(UI) 검사service_candidates → 서버 통신(API) 검사database_hints → 데이터베이스(DB) 검사*_scenario_command × 7*_repair_command × 7
.codex/loopy-era/qa-scenarios.json 파일로 출력
id, requiredcommand, repair_commandrequired_coverage[]evidence_contract 규격
scenario_checks() 반복 검사app_candidatesbutton, event_click, state_changeapp_candidatesmodal_popup, open_closeapp_candidatesconfirm_dialog, accept_cancelapp_candidatesalert_dialog, message_visibilityapp_candidatesconsole_errors, console_warningsconsole_errors: 0 오류 0 필수service_candidatesrequest, response, error_handlingdatabase_hintswrite, read, state_assertionstatus: "pass"/"ok"/"success", executed: true, coverage: [...] (확인해야 할 항목 목록과 일치),
browser-console-clean 즉 브라우저 콘솔에 오류가 없는지 보는 검사는 추가로 console_errors: 0 이 반드시 있어야 합니다.
이 중 하나라도 빠지거나 안 맞으면 그 검사는 실패(FAIL) 처리됩니다.
// qa-scenarios.json 파일이 어떻게 생겼는지 예시 { "scenarios": [ { "id": "ui-button-event", "required": true, "command": "python3 .codex/scripts/test-button-event.py", "repair_command": "python3 .codex/scripts/repair-button-event.py", "required_coverage": ["button", "event_click", "state_change"], "evidence_contract": { "status": "pass | ok | success", "executed": true, "coverage": ["...확인해야 할 항목들..."] } }, { "id": "browser-console-clean", "required": true, "evidence_contract": { "console_errors": 0, // 필수 — 오류가 0이어야 통과(PASS) "coverage": ["console_errors", "console_warnings"] } } ] }
init-project-runtime.py가 만들어 내는 project-profile.json에는, 검사별로 "실행 명령"과 "고치는 명령"을 담는 항목이 14개 새로 들어갔습니다. 이 항목들이 qa-scenario-gen.py → qa-cycle-runtime.py 로 이어지는 QA 전체 과정을 조종합니다.
self-improve-trigger.sh가 5군데에서 "고칠 게 있다"는 신호를 모읍니다. 이미 처리한 신호는 걸러내(중복 방지)
~/.codex/pending/self-improve-{key}.json라는 대기 파일에 저장합니다. 이렇게 모인 신호가 있을 때만, 일꾼(worker)이 AI(LLM)에게 수정을 요청합니다.
git worktree add --detach HEAD (실패하면 통째로 복제해서 대신, 그리고 원본 백업)codex -o output.json < prompt — 답은 정해진 형식(JSON)으로만 받도록 강제 (결과·수정 범위·검증 항목)
Claude Code에서 쓰던 /team · /init-project · /qa-cycle · /qa-scenario-gen 이 네 가지 핵심 명령이 Codex 환경에서 어떻게 다시 만들어졌는지 비교합니다. 공통된 방향은 하나입니다 — AI에게 말로 시키던 것을, 파이썬 프로그램이 직접 실행하도록바꾼 것입니다.
/qa-cycle 를 자동으로 이어서 실행team-runtime.py --execute --json 이라는 명령 하나로 실행ThreadPoolExecutor (파이썬 병렬 실행 도구)로 여러 일꾼을 실제 동시 실행blocker_total=0이면(문제가 없으면) 계획 단계에서 status: "skip" 을 돌려주고 건너뜀| 핵심 차이 | ||
|---|---|---|
| 실행 방식 | AI가 전문 에이전트를 불러 쓰고, 작업 추적 기능으로 진행을 따라감 | 파이썬 프로그램이 일꾼 프로세스를 직접 관리 (병렬 실행 도구 사용) |
| 동시 실행 보장 | Promise.all() 방식으로 묶어 실행하되, 실제 동시 실행 여부는 에이전트 판단에 맡김 |
결과(JSON)에 parallel_execution: true 라고 분명히 적혀 있는지 확인 |
| 수정 안전성 | 코드를 바로 고치고, 실패하면 자동 수리 도구로 재시도 | HARD 손대도 되는지 검문하는 게이트 + 별도 작업 사본에서만 수정 |
| QA 연결 | 4단계에서 /qa-cycle 명령을 직접 불러 실행 |
9단계 qa_cycle에서 지휘 프로그램이 자동 실행 |
.claude/CLAUDE.md, .claude/skills/~/.claude/skills/{project}-scaffold/ 자동 생성settings.json 에 외부 도구 연결(MCP) 설정 포함auto-issue.md, qa-scenarios.md 자동 생성.codex/rules/project-conventions.rules.codex/skills/ (backend-patterns, frontend-patterns, qa-strategy)~/.codex/skills/{project}-scaffold/ 자동 생성project-profile.json에 검사용 명령 14개 항목 포함| 핵심 차이 | ||
|---|---|---|
| 설정 위치 | .claude/ → Claude Code 전용 폴더 |
.codex/ → Codex 전용 폴더, .claude/ 에 기대지 않음 |
| 실행 빈도 | 사람이 직접 /init-project 불렀을 때 한 번 |
AUTO 매 반복 회차 시작 때 자동 실행 |
| 검사 항목 설정 | qa-scenarios.md 라는 텍스트 문서로 생성 |
project-profile.json에 실행·수정 명령 14개 항목으로 담음 |
| 외부 도구 연결(MCP) 설정 | settings.json안에 외부 도구 서버 포함 |
config.toml이라는 별도 파일로 분리, 이 단계 담당 아님 |
agent-browser로 실제 화면을 눌러 보며 검증.qa-cycle-passed 라는 통과 표시 파일로 관리qa-cycle-runtime.py 라는 파이썬 프로그램, 결과는 JSON으로 출력--max-rounds N 값으로 반복 횟수 조절scenario_checks(): 검사 목록을 읽어 7가지 검사 실행.codex/loopy-era/qa-cycle-report.json 에 결과 저장| 핵심 차이 | ||
|---|---|---|
| 화면(UI) 테스트 | agent-browser + web-qa-tester 로 실제 브라우저에서 눌러 보며 확인 |
scenario_checks()가 검사 목록의 명령을 실행하고 증거를 검증 |
| 실패 분류 | 심각도(치명·높음·보통·낮음) 기준 | failure_labels (build/type/lint/test) + repair_strategy.source |
| 자동 수정 | 자동 수리 에이전트를 최대 4번 호출 | qa_fix_retry 단계에서 team-runtime.py를 다시 돌리고 고치는 명령 실행 |
| push gate | HARD 통과 표시 파일 + 1시간 유효 해시 검증으로, 통과 못 하면 올리기(push)를 막음 | 지표로만 추적하고, 올리기를 막는 검문소는 따로 없음 |
docs/qa-test-plan.md 생성 — 테스트 항목(TC)마다 번호를 매김qa-scenario-gen.py 라는 독립 파이썬 프로그램으로 구현project-profile.json 을 읽어 7가지 검사 중 무엇이 필요한지 자동 결정qa-scenarios.json 파일 출력 → qa-cycle-runtime.py 가 그 파일을 받아 사용
.codex/ralph-loop/state.json 라는 상태 파일 기준입니다. 11번째 반복에서 l6_blocker_count = 0 즉 "남은 치명 문제 0개"를 달성했습니다. "멈춰도 된다"는 완료 조건을 채워 상태는 status: completed(완료)가 됐고, 작업 배분(team_plan)은 남은 문제가 없어 건너뛰었습니다.
self-improve-smoke.sh는 문법만 보는 게 아니라, 진짜로 임시 git 저장소를 하나 만들어 전체 흐름이 처음부터 끝까지 도는지 확인합니다. 이 통합 점검(smoke)을 통과해야만, 앞서 본 "남은 문제 개수" 측정(verify-l6.sh)에서 문제로 잡히지 않습니다.
/qa-scenario-gen도 따로 부르던 명령에서 2단계 프로그램으로 완전히 옮겨져, 통과 증거(evidence contract)에 따른 자동 검증이 가능해졌습니다.
다만 브라우저로 화면을 직접 눌러 보는 검증과, 코드 올리기를 막는 검문소(push gate)는 아직 옮기지 못했습니다.