blueprint_updater.py Knowledge Graph Live 통합 작업 결과
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로 방지 |
잔여 이슈
-
graph.json이 빠르게 변동 중: 8,894/35,265 (현재) → 이전 교차검증 때는 182/376 이었음. Codex 1의 graphify 복구가 진행 중이라 노드/엣지 수가 변동 → 매 크론 실행마다 changed=True가 되어 저장 발생. 정상 동작이지만 빈번한 파일 쓰기 발생 가능. 해법 불필요 — graph.json 안정화되면 자연 해소.
-
mtime 서식 의존성:
datetime.fromtimestamp(..., tz=KST)사용 → 시스템 timezone과 무관하게 KST로 고정. 추후 시스템 이전 시 KST 고정 특성 재확인 필요. -
Phase 4 서술 고정: 현재 "Codex 측 graphify 복구 작업 진행에 따라..." 문구는 하드코딩. Phase 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 크론 실행 결과 확인.