start-harness.sh를 시작점으로 삼는 자가개선 하네스를 통째로 뜯어본 글입니다.
하네스란, AI가 스스로 코드를 고치고 "다 됐다"는 말 대신 실제 증거로 검증하도록 강제하는 자동화 장치입니다.
이 글은 그 전체 구조를 정리합니다.
순서대로 이어지는 14단계 작업, 고칠 곳을 알려주는 단서 5종을 모으는 방법,
핵심 기능이 최소한 돌아가는지 빠르게 확인하는 8가지 기본 점검,
그리고 AI가 사람 없이 스스로 수정안을 만들어 적용하는 방식까지 살펴봅니다.
결론부터 말하면, 이 시스템은 사람이 시키지 않아도 스스로 굴러가는 자동 개선 루프입니다. AI가 "여기 고칠 게 있다"는 단서를 직접 찾아내고, 언어 모델(문장을 이해하고 만들어내는 AI)을 불러 수정안을 만들고, 그 수정안이 정말 맞는지 검증한 뒤 적용합니다. 이 과정을 사람 개입 없이 반복합니다. 관련 파일은 모두 ~/.codex/ 폴더 아래에 모여 있고, cc-sync라는 동기화용 프로젝트를 거쳐 여러 컴퓨터에 똑같이 맞춰집니다.
l6_blocker_count입니다. 통과를 막는 결함이 몇 개 남았는지 센 값으로, 목표는 0개입니다.이 시작 스크립트가 할 수 있는 일은 크게 5개의 하위 명령으로 나뉩니다. 각 명령이 무엇을 하는지는 스킬 설명서 파일 .codex/skills/start-harness/SKILL.md에 정의돼 있습니다.
# start — 하네스 전체를 켬 (가장 많이 쓰는 명령) bash start-harness.sh start --project-root "$PWD" loop-era-supervisor.sh ensure ← 감시 프로그램이 떠 있도록 보장 ralph-loop.sh start [args] ← 이 프로젝트를 관리 목록에 등록 ralph-loop.sh tick --force ← 기다리지 않고 즉시 1회 실행 pretty_status() ← 감시 프로그램과 작업 프로세스 상태 출력 # smoke — 환경이 제대로 갖춰졌는지 빠르게 점검 bash start-harness.sh smoke --project-root "$PWD" self-improve-smoke.sh ← 8가지 통합 테스트 loop-era-smoke.sh ← 반복 루프 전용 기본 점검 verify-l6.sh ← 통과를 막는 결함 개수 측정 adversarial-review-l6.py ← 트집 잡듯 파고드는 코드 리뷰 # stop — 중지 (--global-supervisor를 붙이면 감시 프로그램까지 끔) bash start-harness.sh stop --project-root "$PWD" [--global-supervisor]
ralph-loop.sh는 실제 관리 프로그램인 loop-era-supervisor.py를 명령줄에서 간편하게 부르도록 감싼 껍데기(래퍼)입니다. start 명령을 실행하면, 저장소 안에 자가개선 실험에 필요한 기본 파일들을 자동으로 깔아 둡니다.
ralph-loop.sh start seed_repo_artifacts() cp ~/.codex/autoresearch/{verify-l6.sh, adversarial-review-l6.py} → .codex/autoresearch/ (없으면 자동 복사) python3 loop-era-supervisor.py register [args] loop-era-supervisor.sh start ralph-loop.sh tick → python3 loop-era-supervisor.py run-once ralph-loop.sh stop → python3 loop-era-supervisor.py cancel ralph-loop.sh status → python3 loop-era-supervisor.py status
loop-era-supervisor.py안에 정해 둔 순서표 PHASE_ORDER대로 14단계가 차례차례 실행됩니다. 각 단계의 결과는 진행 기록 phase_history에 남고, 지표가 어떻게 변해 왔는지는 results.tsv라는 표 파일에 저장됩니다.
self-improve-trigger.sh는 여러 곳에서 "고칠 게 있다"는 단서를 모아 처리 대기 파일 ~/.codex/pending/self-improve-{key}.json에 저장합니다. 이미 처리한 단서는 "처리 완료" 표시(ack) 파일로 걸러내, 같은 일을 두 번 하지 않습니다.
| 단서 종류 | 어디서 모으나 | 무엇을 뜻하나 |
|---|---|---|
| fix_commit | git log --grep='^fix:' |
작업 중 만든 버그 수정 커밋입니다. 어떤 실수가 반복되는지 배우는 재료가 됩니다. |
| bug_fixer_retry | .codex/logs/*.jsonl |
버그 수정 담당 AI가 몇 번이나 다시 시도했는지 남긴 기록입니다. 자동 수정이 반복된 패턴을 잡아냅니다. |
| recurrence | check-recurrence.py |
과거 자가개선 이력과 버그 수정 커밋을 겹쳐 봅니다. 같은 키워드가 2번 이상 나오면 신호로 잡습니다. |
| telemetry | self-improve-telemetry.py |
사용자가 불만을 드러낸 표현을 분석합니다. 한국어 표현도 잡습니다("아니요", "안 보이", "중복" 등). |
| adversarial_finding | adversarial-review-l6.py |
비판적 리뷰에서 찾은 중대·주요 결함(P1/P2)입니다. 다음 반복 회차에 자동으로 다시 처리 목록에 넣습니다. |
# self-improve-trigger.sh 흐름 project-scope.py → 프로젝트 고유 키 결정 # 단서 수집 git log --since=$SESSION_START --grep='^fix:' → fix_commit[] .codex/logs/*.jsonl | grep "bug-fixer" → bug_fixer_retry[] check-recurrence.py $PROJECT_ROOT → recurrence[] self-improve-telemetry.py --project-root $ROOT → telemetry[] # 처리 완료(ack) 걸러내기 (중복 제거) ~/.codex/state/self-improve-acks/{key}.json # 단서가 있으면 처리 대기 파일에 저장 ~/.codex/pending/self-improve-{key}.json # 후처리 (있으면 실행) rule-effectiveness-check.sh ← 규칙 효율성 검증 soft-to-hard-promoter.sh ← 권고(SOFT) 규칙을 강제(HARD) 규칙으로 승격
이 시스템의 심장 격인 부분입니다. 실제로 언어 모델(AI)을 불러 개선 수정안을 만들고 적용합니다. 작업은 git worktree(원본 저장소를 건드리지 않도록 복제한 별도 폴더)에서 진행하므로 원본이 망가질 걱정이 없고, 실패하면 백업에서 자동으로 되돌립니다.
self-improve-worker.py run --project-root $ROOT │ ├── [재실행 대기] CODEX_SELF_IMPROVE_COOLDOWN_SECONDS=900 (15분) ├── [lock] ~/.codex/state/self-improve-workers/{key}.lock │ ├── load_pending() + unacked_signals() 아직 처리 안 한 단서만 걸러내기 │ ├── [격리된 작업 폴더] │ git worktree add --detach HEAD │ backup_codex() → temp/codex-backup/ │ ├── [언어 모델 호출] │ build_prompt(root, signals[:10], team_context) │ write_schema(output_schema.json) │ codex --model gpt-5.4 -o output.json < prompt │ ├── [결과 검증] │ patch_scope: ["project"] | ["codex"] | ["project","codex"] │ verification_checks: │ file_contains → 파일 내용 포함 여부 │ repo_script → .codex/autoresearch/*.sh 실행 │ codex_smoke → self-improve-smoke.sh │ git_diff_check → 바뀐 내용(diff) 확인 │ ├── [수정안 적용] │ patch_scope=["codex"] → ~/.codex/ 직접 수정 ✅ │ patch_scope=["project"] → 대기열에 저장 (저장소가 깨끗해야 적용) ⚠️ │ ├── self-improve-ack.sh ← 처리한 단서에 완료 표시(ack) ├── self-improve-smoke.sh ← 적용 후 기본 동작 점검 └── self-improve-log.sh ← 이력 기록
patch_scope=["project"]는 저장소가 깨끗한 상태, 즉 git status --porcelain 명령 결과가 비어 있어 아직 커밋하지 않은 변경이 하나도 없을 때만 곧바로 적용됩니다. 저장 안 된 변경이 남아 있으면 ~/.codex/state/self-improve-queues/{key}/ 폴더에 수정안 파일(.patch)로 대기시킵니다.
검증은 두 겹으로 진행합니다. 하나는 숫자로 세는 검증(verify-l6.sh)이고, 다른 하나는 내용을 트집 잡듯 따지는 검증(adversarial-review-l6.py)입니다. 두 검증 모두 결과를 JSON 형식으로 출력하고, 감시 프로그램이 그 결과를 읽어 다음 단계로 넘어갈지 결정합니다.
# verify-l6.sh — 통과를 막는 결함 개수 측정 필수 파일 17개 존재 확인: .codex/autoresearch/verify-l6.sh .codex/autoresearch/adversarial-review-l6.py .codex/scripts/session-start.sh .codex/scripts/memory-bank-session-end.sh .codex/scripts/self-improve-trigger.sh .codex/scripts/self-improve-check.sh .codex/scripts/self-improve-worker.py .codex/scripts/team-runtime.py .codex/scripts/loop-era-supervisor.py .codex/scripts/init-project-runtime.py .codex/scripts/qa-cycle-runtime.py .codex/scripts/check-recurrence.py .codex/scripts/install-git-hooks.sh .codex/skills/self-improve/SKILL.md .codex/skills/ralph-loop/SKILL.md .codex/skills/team/SKILL.md ... (+1 more) python3 -m py_compile × 10개 ← 파이썬 코드 문법 검사 bash -n × 4개 ← 배시 코드 문법 검사 self-improve-smoke.sh ← 통합 기본 점검 (건너뛸 수 있음) → {"metric": "l6_blocker_count", "value": N, "status": "pass/fail"} # adversarial-review-l6.py — 내용을 따지는 리뷰 필수 산출물이 있고 비어 있지 않은지 (10개) apply.sh / sync.sh에 자가개선 파일 동기화가 들어 있는지 self-improve-trigger.sh가 특정 AI(Claude)에 강하게 묶여 있는지 탐지 self-improve 설명서의 알림 경로가 올바른지 확인 self-improve-smoke.sh의 set +e / STATUS=$? / [STATUS -eq 1] 패턴 git 훅이 Codex 실행 단계로 이어지는지 여부 → {"blocker_count": N, "findings": [...], "status": "pass/fail"}
self-improve-smoke.sh는 코드 문법만 훑고 끝나지 않습니다. 진짜 임시 git 저장소를 하나 만들어, 전체 과정을 처음부터 끝까지 돌려 보는 통합 테스트까지 포함합니다.
STATUS=1이 나와야 통과입니다.status=stale_running 즉 "멈춘 채 방치됨" 상태로 잡히는지 확인합니다. 이어서 되살리기를 시험 실행하면 running=False 상태로 정리됩니다.status=backoff, last_result=escalation_required, disabled_until 같은 값이 설정돼, 잠시 물러나 쉬는 상태로 바뀌는지 확인합니다.patch_scope=["codex"])은 곧바로 적용됩니다. 섞인 수정(["project","codex"])은 Codex 부분만 즉시 적용하고, 프로젝트 부분은 대기열에서 기다립니다.| 구성요소 | 완성도 | 비고 |
|---|---|---|
| 단서 수집 과정 | ✅ 100% | 단서 5종, 한국어 표현까지 인식 |
| 자동 수정 실행 | ✅ 100% | 격리 폴더, 백업·복구, 4종 검증 |
| 결함 개수 지표(L6) | ✅ 100% | 숫자 기준으로 채택·폐기 판정 |
| 기본 동작 점검 장치 | ✅ 100% | 8가지 통합 테스트 자동화 |
| 감시 프로그램(상시) | ✅ 100% | 프로세스 번호, 자동 실행, 생존 신호, 멈춘 작업 복구 |
| 14단계 실행 순서 | ✅ 100% | 순서표대로 완전 구현 |
| git worktree 격리 | ✅ 100% | 복제(clone) 대체 경로 포함 |
| 처리 완료·실패 표시 체계 | ✅ 100% | 같은 단서를 두 번 처리하지 않음 |
| 프로젝트 파일 수정 적용 | ⚠️ 70% | 저장소가 깨끗해야 적용, 아니면 대기열 |
| 도구 간 동기화 | ⚠️ 60% | cc-sync의 apply.sh·sync.sh에 의존 |
| 강제 규칙 자동 승격 | ⚠️ 70% | 승격 스크립트는 있지만 처리 깊이에 한계 |
start-harness.sh로 켜는 순간부터 14단계 실행 순서, 8가지 기본 동작 점검, 단서 5종 수집, 격리 폴더, 중복 처리 방지까지 매우 정교하게 짜여 있습니다.