OpenClaw·Hermes 마이그레이션 (2/13) — 1년 자산 중 무엇을 살리고 버릴까

다수의 운영 스크립트를 코드 리뷰하고 보존 / 부분 보존 / 폐기로 분류한 기록


이 글이 전달하는 것

  • 레거시 에이전트 시스템을 후속 시스템으로 옮길 때 쓸 수 있는 자산 분류 기준 (보존/부분 보존/폐기 3단계)
  • Strangler Fig + Subset Migration 전략을 메모리 파이프라인에 적용한 구체 사례
  • 다수의 스크립트를 LOC·외부 의존성·대체 가능성 축으로 판정한 결과
  • 비대해진 단일 파일(1310 LOC)을 마이그레이션 기회에 슬림화하는 방법

문제 정의: 전부 옮길까, 버릴까

오픈클로 인벤토리는 다수의 에이전트, 다수의 스케줄러 / 데몬, 다수의 운영 스크립트로 구성되어 있다. 후속 시스템인 헤르메스로 이관할 때 선택지는 둘 중 하나가 아니다. 전부 이식하면 누적 부채가 따라오고, 최소만 이식하면 축적된 도메인 로직을 버린다. 코드 리뷰 기반 자산 분류가 이 간극을 해결한다.


결정 컨텍스트 — 분류 기준을 만드는 5개 골조

자산을 분류하기 전에 이관 대상 아키텍처가 고정되어 있어야 한다. 분류 기준은 "이 코드가 목적지 구조에 들어갈 수 있는가"에서 도출되기 때문이다.

  • 전략: Strangler Fig(점진 교체) + Subset Migration(부분 이식)
  • 메모리: SQLite + Python 라이브러리(memcore). 데몬 없음. 별도 프로세스가 아니라 라이브러리로 import해서 쓰는 구조
  • 폴더: ~/Hermes/로 분리. ~/Project/의 오픈클로는 read-only 백업으로 보존
  • 에이전트: '헤르메스 관리' 신규 생성. '오픈클로 관리'는 백업 전담으로 강등
  • 컷오버: 듀얼 실행(같은 기능을 양쪽에서 돌리며 비교) → 검증 통과 후 컷오버

이 5개가 정해지면 분류 기준이 자동으로 파생된다. "memcore 라이브러리에 흡수 가능한가? Hermes profile에 녹일 수 있는가? 대체재가 이미 있는가?"


보존 (이식 필수)

파일 LOC 이식 형태 가치
user-pattern-stage.py 260 memcore.dialectic 모듈 최고. U-tag 3-phase(관찰→가설→검증), Honcho 영감, anti-bias guard
confidence-decay.py 82 memcore cron tick opinions confidence 0.02 감쇠, <0.30 제거
topics-validate.py 131 memcore 정합성 체크 bank ↔ topics 일관성
topics-expand.py 186 memcore 자동 등록 신규 파일 자동 등록
bank-lint.py 176 memcore validator Retain 태그 포맷 검증, 데이터 무결성
entity-audit.py 152 memcore stale 감지 30일 stale, SQLite timestamp 쿼리로 동등
docs-snapshot.sh 141 Hermes cron payload docs 변경 감지, URL만 변경
release-check.sh 66 Hermes cron payload 버전 변경 감지

판정 원리

보존 판정의 핵심 축은 외부 의존성 부재다. 보존 대상 전부 표준 라이브러리만 사용하고, 파일 I/O는 lib_common.py를 경유한다. 이관 작업은 lib_common.pymemcore.io로 치환하는 단일 조작으로 귀결된다. 평균 175 LOC, 단위 테스트로 동등성 검증이 가능한 크기다.

최우선 자산: user-pattern-stage.py

이 파일은 사용자 발화 패턴을 관찰→가설→검증의 3단계 변증법으로 추적해 확증편향을 차단하는 로직을 구현한다. 후속 시스템(Hermes)에 동등 기능이 존재하지 않는다. 이 한 파일의 이관 여부가 마이그레이션의 정당성 지분 중 상당 부분을 차지한다.


부분 보존

파일 LOC 처리
bank-size-watch.py 176 SQLite 전환 후 의미 약화. MemTree split 로직 일부만
proactive-exception-alerts.py 1310 과비대. 11개 escalation reason 판정 로직만 추출(~300 LOC), 알림 라우팅과 컨텍스트 수집은 Hermes gateway/hook에 위임

비대 파일 슬림화 패턴

proactive-exception-alerts.py는 1310 LOC로 누적 부채가 가장 큰 파일이다. 구조를 해부하면 세 층으로 나뉜다.

  1. 판정 로직 (~300 LOC): 11개 escalation reason을 평가하는 핵심 — 이관 대상
  2. 알림 라우팅: Hermes gateway로 위임 가능
  3. 컨텍스트 수집: Hermes hook 인프라로 위임 가능

마이그레이션은 이런 비대 파일을 슬림화할 자연스러운 진입점을 제공한다. 1310 → 300 LOC 축소는 기능 손실 없는 부채 정리다. 2, 3번 레이어는 목적지 인프라에 동등 기능이 있으므로 재작성 비용이 0에 가깝다.


폐기

파일 LOC 대체
heartbeat-tick.py 262 Hermes cron + on_turn_start hook으로 100% 대체

heartbeat-tick.py는 목적지 인프라(cron + on_turn_start hook)가 동등 기능을 기본 제공한다. 이관 가치 없음. 폐기는 물리 삭제가 아니라 read-only 백업(~/Project/)으로의 격리를 의미한다. 참조 필요 시 언제든 열람 가능한 상태로 남긴다.


코드 리뷰 체크리스트 (재사용 가능)

자산 분류 시 각 파일에 다음 질문을 순서대로 던지면 판정이 수렴한다.

  1. 목적지에 동등 기능이 있는가? — 있으면 폐기 후보
  2. 외부 의존성이 있는가? — 없으면 이식 비용 낮음 → 보존 가능
  3. 파일 크기가 책임과 맞는가? — 과비대하면 부분 보존(슬림화)
  4. 고유 도메인 로직이 있는가? — 있고 재구현 비용이 크면 최우선 보존
  5. 테스트로 동등성 검증이 가능한가? — 가능해야 듀얼 실행 컷오버 성립

정리된 원리 4가지

  1. 이식 난이도는 LOC보다 의존성 그래프에서 결정된다. 평균 175 LOC 규모의 보존 자산들이 빠르게 이관 가능한 이유는 lib_common.py 외 외부 의존이 없기 때문이다.
  2. 작업량은 이식이 아니라 검증에서 발생한다. 코드 이관 자체는 1~2일 규모, 듀얼 실행 검증이 더 오래 걸린다.
  3. 고유 도메인 로직은 LOC 대비 가치가 비선형적이다. user-pattern-stage.py는 260 LOC지만 대체재 부재로 최우선 자산이 된다.
  4. 마이그레이션은 부채 정리의 자연 기회다. 과비대 파일(1310 LOC)의 슬림화는 별도 리팩터링 프로젝트보다 마이그레이션 컨텍스트에서 수행할 때 비용이 낮다.

적용 가능 범위와 열린 질문

이 분류 기법은 "레거시 시스템 → 후속 시스템"의 메모리/파이프라인 계층에 적용하기 쉽다. UI 계층이나 데이터 스키마 계층에는 동일 기준이 그대로 통하지 않는다. 외부 의존성 축 대신 스키마 호환성, 데이터 볼륨, 마이그레이션 다운타임이 더 지배적인 변수가 된다.

열린 질문: - 보존 판정이 내려진 자산들이 duel-run 검증에서 실제로 동등성을 보이는가 — 아직 데이터로 확인되지 않은 가정이다. - 부분 보존 사례의 슬림화 비율(1310 → 300)이 다른 파일에도 재현 가능한 패턴인지, 아니면 proactive-exception-alerts.py의 특이 구조 때문인지 분리 필요.


시리즈 전체 안내: 시리즈 목차

댓글

이 블로그의 인기 게시물

"LLM 핵심 학습 (1/6) — 기본: 토큰화·임베딩·어텐션·위치 인코딩"

"LLM 핵심 학습 (2/6) — 파인튜닝: LoRA·QLoRA·증류·Adapter"

"ML 기초 학습 (1/9) — 머신러닝과 sklearn: 학습의 좌표계"