# Migration — from hanarang-harness > 기존 [`hanarang/openclaw-harness`](https://git.nabomhalang.co.kr/hanarang/openclaw-harness) (현재 private archive) 에서 hanarang-rails 로의 이관 가이드. ## 요약 | 항목 | 기존 (hanarang-harness) | 신규 (hanarang-rails) | |---|---|---| | 런타임 | bash + Node hooks + Lobster | Node 22 + TypeScript (strict) | | 오케스트레이션 | Lobster 워크플로우 (.lobster 파일) | XState v5 머신 | | 상태 | 파일 분산 (`state/`) | SQLite 단일 파일 | | 핸드오프 | 디스코드 멘션 | FSM state transition | | 디스코드 | bridge.sh (curl) | discord.js v14 (알림 전용) | | DoD 검증 | 텍스트만 (기계 판정 불가) | Zod schema + validator | | Skill 진입 | 권고 | hook 기반 강제 | | 재시도 | 없음 / 약함 | exponential backoff + escalation | | QA | 선택적 | 체크리스트 강제 | ## 자산 매트릭스 ### ✅ 유지 / 포팅 | 자산 | 위치 | 신규 매핑 | |---|---|---| | `scaffold.sh` | 기존 `scripts/scaffold.sh` | `rails scaffold` 서브커맨드 | | `install.sh --role` | 기존 `scripts/install.sh` | `rails install --role` 서브커맨드 | | `doctor.sh` | 기존 `scripts/doctor.sh` | `rails doctor` + env prereq 통합 | | 에이전트 md (planner/worker/reviewer/deploy-manager) | 기존 `agents/*.md` | `agents/` 로 복사, XState actor 의 system prompt 소스 | | 자매별 특화 프롬프트 (`agents/hanarang/*`) | 기존 | 동일 경로 유지 | | `.plans/` 디렉토리 구조 컨벤션 | 기존 | **계승**. 단 `.plans/rails/` 추가 (contract / qa artifact) | | 디스코드 포럼 포스트 컨셉 | 기존 `bridge.sh` 일부 | discord.js 로 재구현 | | Hook 3종 아이디어 | 기존 `hooks/*.js` | enforcement hook 으로 재설계 (Sprint 002) | | 프로젝트 타입별 배포 분기 | `deploy-manager.md` 최근 업데이트 | `erang` actor 의 project-type-detector 로 포팅 | ### ⚠️ 재검토 후 부분 계승 | 자산 | 상태 | 이유 | |---|---|---| | Lobster 워크플로우 파일 (`workflows/*.lobster`) | **폐기** | 결정성 부족의 근본 원인. XState 로 전면 대체. 단, "4단계 Plan→Impl→Review→Deploy" 컨셉은 계승 | | bridge.sh | **폐기** | curl 기반 브릿지는 장애 많음. discord.js 로 교체 | | thinking_tier 파라미터 | **제한** | xhigh 금지, high 까지만 | | route-task.sh | 재평가 | rails 에서는 FSM 이 라우팅 담당, 별도 필요 여부 검토 | | GLM / GPT 모델 라우팅 룰 | 계승 | `rails models.yaml` 로 정리 | | install.sh 의 에이전트 격리 로직 | 계승 | role 기반 격리 유지 | ### ❌ 폐기 | 자산 | 이유 | |---|---| | 워킹트리의 .lobster 파일 | 결정성 없음, LLM 의존 | | 멘션 기반 자매 간 핸드오프 | F3 / F4 의 원인 | | "build 통과 = 완료" 판정 | F2 의 원인 | | "환경 없음 → skip" 용인 | F6 의 원인 | | 무제한 timeout (또는 기본값 너무 김) | F5 의 원인 | ## 마이그레이션 단계 (운영자 관점) ### Step 0 — 읽기 (사전) 1. `.plans/failure-audit.md` 를 전체 읽는다 (F1~F6 이해) 2. `.plans/OVERVIEW.md` 의 성공 기준을 검토 3. 기존 hanarang-harness-archive 를 **참조만**. 코드는 복사하지 않는다 (인용 OK) ### Step 1 — 실행 환경 준비 (이랑이 역할) 1. `pnpm install` 로 rails 설치 2. `rails doctor` — Node 22, pnpm, SQLite, OpenClaw 커맨드 확인 3. `.env` 작성 (`DISCORD_TOKEN`, `DISCORD_GUILD_ID`, `GITEA_TOKEN`, …) 4. `rails migrate from-hanarang-harness /home/erang/hanarang-harness-archive` 실행 → 포팅 레포트 ### Step 2 — 4자매 배포 1. Planner 호스트: `rails install --role planner` 2. Generator 호스트: `rails install --role generator` 3. Evaluator 호스트: `rails install --role evaluator` 4. Infra 호스트: `rails install --role infra` 5. 각 자매의 `openclaw.json` 에 rails skill 등록 6. 각 자매에 `rails doctor --role ` 로 확인 ### Step 3 — 첫 프로젝트 (아랑) 1. 아랑 프로젝트는 이미 `hanarang/arang` Gitea repo 존재 2. `cd /home/erang/projects/arang && rails bind` 3. `rails run "Sprint 002 — Live2D 아바타"` (기획 기반) 4. end-to-end 완주 확인 5. 실패 시 `rails status ` + 로그 분석 ### Step 4 — 레거시 철거 1. 4자매 LXC 에서 기존 hanarang-harness 진입점 비활성화 (`.openclaw/skills/hanarang-harness/` 제거) 2. `bridge.sh` 프로세스 종료 3. `hanarang-harness-archive` 는 읽기 전용 상태로 보존 (절대 삭제 금지) 4. Gitea `openclaw-harness` repo 는 private 상태 유지 (이미 Sprint 000 에서 전환 완료) ## 회고 포인트 마이그레이션 후 SPRINT-007 완료 시점에서 다음 회고 문서 작성: - `.plans/retro/hanarang-harness-retro.md` — 기존 하네스의 교훈 - `.plans/retro/hanarang-rails-v1.md` — rails v1 설계 결정 재평가 - 추후 v2 후보 기능 목록 ## 롤백 경로 만약 rails 가 실패하면: 1. `hanarang-harness-archive` 를 checkout 해서 기존 bash 스크립트 복구 2. 4자매 LXC 에 기존 install.sh 재실행 3. `bridge.sh reset` 으로 디스코드 브릿지 부활 4. 실패 원인을 `.plans/retro/rails-failure.md` 에 기록하고 rails 개선 단, **하네스 자체가 실패** 라는 건 재설계 원칙이 잘못됐다는 뜻이니 rollback 전에 반드시 사용자(자기야) 승인.