#!/bin/bash # SessionStart hook — 레포 memory/org/ → 중앙 $HOME/.claude/nerdnavis-memory/ 단방향 sync # git pull 직후 원격 반영분을 중앙에 최신화. unflushed 중앙 변경은 대피 백업. # 2026-04-19 신설 — C34-3 동기화 4계층 (레포 SOT 원칙) REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null) [ -z "$REPO_ROOT" ] && exit 0 REPO_MEM="$REPO_ROOT/memory/org" CENTRAL_MEM="$HOME/.claude/nerdnavis-memory" MARKER_NAME=".memory-junction-marker" LOCK_FILE="$HOME/.claude/.nerdnavis_memory_sync.lock" [ ! -d "$REPO_MEM" ] && exit 0 # 0. Lock (race condition 방지, 5초 타임아웃) ATTEMPT=0 while [ -f "$LOCK_FILE" ] && [ "$ATTEMPT" -lt 5 ]; do sleep 1 ATTEMPT=$((ATTEMPT + 1)) done echo "$$" > "$LOCK_FILE" 2>/dev/null trap 'rm -f "$LOCK_FILE"' EXIT # 1. 중앙 저장소 보장 mkdir -p "$CENTRAL_MEM" 2>/dev/null [ ! -f "$CENTRAL_MEM/$MARKER_NAME" ] && echo "nerdnavis-memory central (C34-16, 2026-04-19)" > "$CENTRAL_MEM/$MARKER_NAME" # 2. unflushed 중앙 변경 탐지 (중앙 mtime > 레포 mtime + HEAD 미반영 의심) CONFLICT_COUNT=0 for cf in "$CENTRAL_MEM"/*.md "$CENTRAL_MEM"/*.json; do [ -f "$cf" ] || continue basename=$(basename "$cf") [ "$basename" = "$MARKER_NAME" ] && continue rf="$REPO_MEM/$basename" if [ -f "$rf" ]; then # 양쪽 존재: mtime 비교 (중앙이 더 새로우면 unflushed 후보) if [ "$cf" -nt "$rf" ]; then # 내용 비교로 확정 (mtime만 다르고 내용 같으면 touch) if ! diff -q "$cf" "$rf" >/dev/null 2>&1; then CONFLICT_COUNT=$((CONFLICT_COUNT + 1)) fi fi else # 중앙에만 있고 레포에 없음 — unflushed 신규 파일 CONFLICT_COUNT=$((CONFLICT_COUNT + 1)) fi done # 3. 충돌 있으면 중앙 대피 후 진행 if [ "$CONFLICT_COUNT" -gt 0 ]; then STAMP=$(date +%Y%m%d%H%M%S) CONFLICT_DIR="$CENTRAL_MEM.conflict-$STAMP" cp -r "$CENTRAL_MEM" "$CONFLICT_DIR" 2>/dev/null echo "⚠️ [Memory Sync] unflushed 중앙 변경 $CONFLICT_COUNT 건 감지 — 대피: $CONFLICT_DIR" >&2 fi # 4. 레포 → 중앙 복사 (marker·conflict 제외, 삭제 동기화 안 함 — 안전망) for f in "$REPO_MEM"/*.md "$REPO_MEM"/*.json; do [ -f "$f" ] || continue basename=$(basename "$f") cp "$f" "$CENTRAL_MEM/$basename" 2>/dev/null done exit 0