loopy-era — Always-on Self-Evolution Harness
사용자가 명시적으로 "tick" 한 번 안 쳐도 시스템이 스스로 측정·학습·정리되도록 만든 8개 LaunchAgent 모음. 30분마다 점수 갱신, 2시간마다 메모리 그래프 동기화, 매일 새벽 한 번 깊은 정리(dream). 모든 결과가 Claude·Codex 양쪽에서 공유되며 메타 변경이력이 GitHub Pages에 라이브 게시됩니다.
개요
loopy-era는 "진짜 자가진화하는 시스템"을 목표로 하는 하네스입니다. comad의 다른 모듈들(brain·ear·sleep·…)이 각자 역할을 수행한다면, loopy-era는 그 모듈들을 주기적으로 측정·갱신·통합하는 메타 레이어입니다.
사용자 개입 없이 다음이 자동으로 일어납니다:
- 30분마다
supervisor.py가 6-phase tick을 돌려 시스템 헬스를 측정·기록 - 2시간마다
kb-sleep-tick.py가 모든.md메모리를kb_facts그래프에 동기화하고 GitHub Pages에 변경이력 게시 - 매일 03:15 KST
auto-dream.sh가 임계 도달 시 comad-sleep 에이전트를 자동 호출 - 모든 산출물이 Claude(
claude/ccc/ccd)와 Codex(cdx) 어느 환경에서든 동일한 5개 MCP 툴로 즉시 조회 - R6 (2026-06): 매일 04:00 야간감사 → 결정 큐, 매주 일 자가학습(learn-weekly), 매주 월 결정 다이제스트 Discord 전송, 매월 evolve 적용, 분기 엔트로피 감사 — "수확→분석→승인요청→적용→계측→감사"의 닫힌 루프 완성
~/.comad/loopy-era/)을 명확히 분리한 첫 모듈입니다. 다른 모듈도 점진적으로 같은 패턴으로 정리될 예정.
8개 LaunchAgent
macOS launchd에 등록되는 백그라운드 데몬 8개. 사용자 머신이 켜져 있는 한 항상 돕니다.
| Label | 주기 | 실행 대상 | LLM |
|---|---|---|---|
com.comad.loopy-era | 30분 (StartInterval 1800s) | bin/supervisor.py tick | ❌ 무사용 (R6: LLM phase 제거) |
com.comad.kb-sleep | 2시간 (StartInterval 7200s) | bin/kb-sleep-tick.py | ❌ 무사용 (rule-only) |
com.comad.auto-dream | 매일 03:15 KST (Calendar) | bin/auto-dream.sh | ✅ Claude (mutex 가드) |
com.comad.nightly-audit | 매일 04:00 KST | bin/nightly-audit.sh | ✅ Claude — 사람 판단 항목만 결정 큐로 |
com.comad.learn-weekly | 매주 일 09:17 | bin/learn-weekly.sh | ✅ Claude (T6 pending 있을 때만) |
com.comad.evolve-monthly | 매월 2일 10:23 | bin/evolve-monthly.sh | ✅ Claude — 적용은 A/B 통과분만 |
com.comad.decision-digest | 매주 월 08:13 | bin/decision-digest.sh | ❌ 무사용 (봇 REST 직접 호출) |
com.comad.entropy-audit | 분기 11일 09:37 (3·6·9·12월) | bin/entropy-audit.sh | ✅ Claude — 90일 기여 증거 감사 (1회차 2026-09-11) |
supervisor 6-phase
supervisor.py가 매 30분 깨어나서 다음 phase를 순서대로 실행합니다. 각 phase는 stdin으로 payload(loopy_dir, state, iteration)를 받고 stdout으로 JSON을 돌려줍니다.
PHASE_ORDER (loopy-era/bin/phases/):
01-init-project # context bootstrap (project metadata)
02-qa-scenario-gen # derive QA scenarios from current state
03-self-improve-trigger # pick the highest-priority pending signal
05-verify-initial # lightweight verification (qa-evidence count)
13-verify-final # final state validation
15-closeout # results.tsv +1 row (+ outcome 지표) + embed/consolidate kb_facts
R6 (2026-06-11)에서 15→6 phase로 슬림화 — worker 미설치로 noop만 반복하던 9개 phase를 제거했습니다 (설계는 git history 보존). phase 15가 memory-bank 통합 지점: cycle 끝에 embed.py+consolidate.py를 incremental 실행하고, results.tsv에 점수와 함께 outcome 지표(fix_ratio 7일 fix-커밋 비율 ↓좋음 · ci_first_pass CI 1차 통과율 ↑좋음)를 기록합니다. LLM 분석은 phase가 아니라 별도 크론(learn-weekly·nightly-audit)이 담당합니다.
kb-sleep tick (2시간)
메모리 본문 동기화 + 임베딩 + GitHub Pages 게시를 한 번에 처리하는 워커. destructive 작업 없음(rule-only consolidate, archive 등 본격 정리는 auto-dream 또는 사용자 명시 dream에 맡김).
kb-sleep-tick.py 의 흐름:
1. extract-facts.py 모든 ~/.claude/projects/*/memory/*.md → kb_facts (idempotent)
2. embed.py 새 fact만 incremental embedding (Ollama nomic-embed-text)
3. consolidate.py SUPPORTS edge 추가 (rule-based, --apply 없음)
4. dream_pending check 임계 도달 시 sleep_state.dream_pending=true
5. publish 메타정보를 _posts/YYYY-MM-DD-mem-log.md 에 append
6. git push stash → pull --rebase → add → commit → push
결과는 /memory-log/YYYY-MM-DD/에서 즉시 확인 가능. 본문은 비공개·메타 통계만.
auto-dream (매일 03:15 KST)
사용자가 "dream" 한 마디 안 해도 매일 새벽 한 번 임계 도달 여부를 체크합니다.
auto-dream.sh 의 결정 트리:
sleep_state.json.dream_pending == true ?
├─ NO → exit 0 "no work to do"
└─ YES
├─ bot-busy.py — 활성 봇이 CPU 사용 중인가? (활동 기반 mutex, R3)
│ ├─ BUSY → skip ccd/cdx와 충돌 회피 (idle 데몬은 차단 안 함)
│ └─ IDLE
└─ headless `claude -p --dangerously-skip-permissions "comad-sleep agent를 실행해 메모리를 정리해줘…"`
→ 15분 timeout, 결과 마지막 50줄을 logs/auto-dream.log 에 기록
소스 vs 런타임 분리
loopy-era는 comad-world의 첫 "코드는 git, 상태는 런타임" 패턴 모듈.
| 위치 | 역할 | git 추적 |
|---|---|---|
comad-world/loopy-era/bin/ | supervisor / phases / hooks / kb-sleep-tick / auto-dream | ✅ |
~/.comad/loopy-era/bin/ | 위 디렉토리로 가는 symlink (호환성) | — |
~/.comad/loopy-era/{logs,pending,phase_history,…} | tick 누적 상태, 로그, 메트릭, 결과 TSV | ❌ |
~/.claude/.comad/memory/facts.sqlite | kb_facts/relations/embeddings (단일 SoT, Claude·Codex 공유) | ❌ |
설치 / 제어
comad-world 루트의 install.sh가 처리하지만, 수동으로도 가능:
# 설치 (interactive)
./install.sh # "Install always-on loopy-era harness?" → y
# 수동 제어
loopy-era/bin/start-harness.sh status # 현재 iteration / metric / state
loopy-era/bin/start-harness.sh tick # 한 번 즉시 실행 (6-phase)
loopy-era/bin/kb-sleep-tick.py --no-push # kb tick (push 안 함)
loopy-era/bin/auto-dream.sh # dream 임계 체크 + 실행
# LaunchAgent on/off
launchctl unload ~/Library/LaunchAgents/com.comad.kb-sleep.plist
launchctl load ~/Library/LaunchAgents/com.comad.kb-sleep.plist
환경변수
| 변수 | 기본값 | 의미 |
|---|---|---|
COMAD_LOOPY_DIR | ~/.comad/loopy-era | 런타임 디렉토리 (state, logs, pending, phase_history) |
COMAD_LOOPY_LLM | auto | claude / codex / auto — dispatcher 분기 (no fallback) |
KB_SLEEP_NO_PUSH | 0 | 1이면 kb-sleep-tick의 git push 비활성화 (로컬 파일 생성만) |
OLLAMA_URL | http://localhost:11434 | 임베딩용 Ollama 엔드포인트 |
관련 모듈: Sleep (kb_facts + 5 MCP 툴 / dream 정책) · Brain (MCP 등록 위치) · Ear (T6 pending 큐 공급)