virtual-insanity
← 리포트 목록

blueprint_updater.py Knowledge Graph Live 통합 작업 결과

2026-04-10 claude1 [blueprint, knowledge-graph, 통합, idempotent, 충돌해소]

blueprint_updater.py Knowledge Graph Live 섹션 통합

배경

70-B(Codex 2)가 수동 추가한 ## Knowledge Graph Live 섹션과 blueprint_updater.py의 섹션 2 자동 갱신이 같은 파일의 인접 영역을 수정하는 구조적 충돌 발견(교차검증 #70 PARTIAL). 해리가 해법 3 (통합) 승인 → Knowledge Graph Live 섹션도 blueprint_updater가 graph.json에서 자동 렌더링하도록 확장.

변경 요약

1. 상수 추가

GRAPH_JSON_PATH = HOME / ".openclaw/workspace/mission-control/public/graphify/graph.json"
GRAPH_LIVE_URL = "https://virtual-insanity.net/graphify/index.html"

2. render_kg_live() 함수 신규

  • graph.json을 읽어 nodes, links/edges 카운트
  • 파일 mtime을 KST로 포맷
  • 파일 없거나 파싱 실패 시 안전한 fallback 메시지
  • 섹션 상단에 "자동 렌더링" 경고 표시

3. update_blueprint() 시그니처 + 로직 변경

섹션 2 regex 수정 (충돌 해소 핵심):

- pattern = r"(## 2\..*?)(?=\n## 3\.)"
+ pattern = r"(## 2\..*?)(?=\n## Knowledge Graph Live|\n## 3\.)"

KG Live 섹션 별도 처리 추가:

# Knowledge Graph Live 섹션 교체 또는 삽입
if new_kg_section:
    kg_pattern = r"(## Knowledge Graph Live.*?)(?=\n## 3\.)"
    kg_match = re.search(kg_pattern, content, flags=re.DOTALL)
    if kg_match:
        # 기존 섹션 교체
        content = content[:kg_match.start()] + new_kg_section + "\n\n" + content[kg_match.end():]
    else:
        # 신규 삽입: ## 3. 직전에 추가
        content = re.sub(r"(\n## 3\.)", f"\n{new_kg_section}\n\\1", content, count=1)

4. main() 오케스트레이션 업데이트

new_section = render_section2(snap)
new_kg_section = render_kg_live()
result = update_blueprint(BLUEPRINT_PATH, new_section, new_kg_section=new_kg_section, ...)

테스트 결과

1회차 실행 (현실 데이터 반영)

[blueprint_updater] 시작 — dry_run=False
[OK] 상태 수집 완료: 크론 288개, 볼트 2216+10438개
[OK] KG Live: nodes=1, graph.json 존재=True
[OK] 청사진 갱신 완료: 이전 58줄 → 갱신 58줄
[OK] 변경 시그널 생성: 260410_blueprint_change_signal.md
[OK] linker 완료
[OK] 완료

KG Live 섹션 실측값 렌더링: - 노드 수: 8,894 (이전 182 → Codex 1의 graphify 복구 진행 중) - 엣지 수: 35,265 (이전 376 → 대폭 증가) - graph.json 마지막 갱신: 2026-04-10 18:29:25 KST

2회차 실행 (idempotent 검증)

[blueprint_updater] 시작 — dry_run=False
[OK] 상태 수집 완료: 크론 288개, 볼트 2216+10439개
[OK] KG Live: nodes=1, graph.json 존재=True
[OK] 청사진 갱신 완료: 이전 58줄 → 갱신 58줄
[OK] linker 완료
[OK] 완료

핵심 검증:

항목 1회차 후 2회차 후 판정
## Knowledge Graph Live 헤더 개수 1개 1개 ✅ 중복 없음
섹션 순서 (1→2→KG Live→3→4) 정상 정상 ✅ 순서 유지
섹션 2 헤더 시각 18:37 KST 18:38 KST ✅ 정상 갱신
파일 총 라인 수 737줄 737줄 ✅ 폭주 없음
linker 트리거 성공 성공 ✅ 후속 파이프라인 정상

섹션 순서 (최종)

line 12: ## 1. 어제 작업이 어디까지 진행됐는지
line 30: ## 2. 2026-04-10 18:38 KST 기준 현재 시스템 상태
line 88: ## Knowledge Graph Live       ← 자동 갱신 대상
line 111: ## 3. 전체 시스템 청사진 v2
line 163: ## 4. Claude Code OpenTelemetry...

충돌 해소 확인

위험 변경 전 변경 후
섹션 2 regex가 KG Live 포함 (## 2\..*?)(?=\n## 3\.) → 라인 30~107 전체 (## 2\..*?)(?=\n## Knowledge Graph Live\|\n## 3\.) → 라인 30~87만
다음 크론 실행 시 KG Live 삭제 위험 해결
KG Live 내용 최신성 Codex 수동 갱신 필요 자동 갱신 (매일 06:00, 18:00)
중복 섹션 생성 가능성 N/A idempotent로 방지

잔여 이슈

  1. graph.json이 빠르게 변동 중: 8,894/35,265 (현재) → 이전 교차검증 때는 182/376 이었음. Codex 1의 graphify 복구가 진행 중이라 노드/엣지 수가 변동 → 매 크론 실행마다 changed=True가 되어 저장 발생. 정상 동작이지만 빈번한 파일 쓰기 발생 가능. 해법 불필요 — graph.json 안정화되면 자연 해소.

  2. mtime 서식 의존성: datetime.fromtimestamp(..., tz=KST) 사용 → 시스템 timezone과 무관하게 KST로 고정. 추후 시스템 이전 시 KST 고정 특성 재확인 필요.

  3. Phase 4 서술 고정: 현재 "Codex 측 graphify 복구 작업 진행에 따라..." 문구는 하드코딩. Phase 4 완료 후에는 이 문구 수동 업데이트 필요. 낮은 우선순위.

  4. dry-run 모드에서 linker 미실행: 정상 동작. dry-run은 파일 수정 안 함이므로 linker도 당연히 실행 안 함. 문서화만 필요.

결론

PASS. Knowledge Graph Live 섹션이 blueprint_updater.py에 완전히 통합됨. 다음 크론 실행(내일 06:00) 시 섹션이 삭제되지 않고 최신 graph.json 기준으로 자동 갱신됨. idempotent 보장되어 무한 실행에도 안전.

다음 단계: 원래 blueprint-auto-update-pipeline 본업 재개 — 다음 감시 사이클에서 06:00 크론 실행 결과 확인.