2026-04-18 17:19:21 +00:00
|
|
|
#!/bin/bash
|
2026-04-22 15:20:06 +00:00
|
|
|
# SessionStart hook — 세션 시작 교훈 환기 체계 6계층 (BT4, 2026-04-23 PD 승인)
|
|
|
|
|
# 구 버전(7일 고정 10건 주입)에서 확장 — PD 지시 "1일 우선 + 필요 시 확장"
|
|
|
|
|
# 관련 규칙: C31-G 자기검증 · C33 조직 공유·기록 체계 · 헌법 원칙 ⑤
|
|
|
|
|
#
|
|
|
|
|
# 6계층 구조
|
|
|
|
|
# 계층 0: 고정 주입 (공백 무관) — 헌법급 feedback 9종(tier: constitutional 자동 선별) · 활성 PD 지시 로그 · 완료 아카이브 최근 5건 · 최근 7일 기각안 · project_context_조직운영 20개
|
|
|
|
|
# 계층 1: 공백 ≤1일 → 1일 윈도우 (feedback·대화로그)
|
|
|
|
|
# 계층 2: 공백 2~7일 → 공백일수 자동 확장
|
|
|
|
|
# 계층 3: 공백 >7일 → 전수 탐색 모드 (개수 기반 feedback 10건·대화로그 프로젝트당 3건)
|
|
|
|
|
# 계층 4: --extend=N 수동 확장 (환경변수 SESSION_RESTORE_EXTEND)
|
|
|
|
|
# 계층 5: 내용축 트리거 (인프라 commit·외부 레포·PD 키워드·기획 경로·순수 코드 연쇄) → 7일 max
|
|
|
|
|
#
|
|
|
|
|
# 모니터링: feedback_session_restore_monitoring.md (pm-auditor 운영 데이터 축적 SOT)
|
2026-04-18 17:19:21 +00:00
|
|
|
|
|
|
|
|
REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null)
|
|
|
|
|
[ -z "$REPO_ROOT" ] && exit 0
|
|
|
|
|
|
|
|
|
|
MEMORY_DIR="$REPO_ROOT/memory/org"
|
2026-04-22 15:20:06 +00:00
|
|
|
DIALOG_DIR="$REPO_ROOT/공유/대화로그"
|
|
|
|
|
PD_LOG_DIR="$REPO_ROOT/공유/PD_지시_트래킹"
|
2026-04-18 17:19:21 +00:00
|
|
|
[ ! -d "$MEMORY_DIR" ] && exit 0
|
|
|
|
|
|
2026-04-22 15:20:06 +00:00
|
|
|
NOW=$(date +%s)
|
2026-04-18 17:19:21 +00:00
|
|
|
|
2026-04-22 15:20:06 +00:00
|
|
|
# ─────────────────────────────────────────────────────────────────────
|
|
|
|
|
# 계층 0: 고정 주입 (공백 무관)
|
|
|
|
|
# ─────────────────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
echo "🏛️ [계층 0 · 고정 주입] 헌법급 feedback · 활성 PD 지시 · 기각안 · project_context"
|
|
|
|
|
echo ""
|
|
|
|
|
|
|
|
|
|
# 0-A. 헌법급 feedback (frontmatter tier: constitutional 자동 선별)
|
|
|
|
|
CONST_FILES=$(grep -l "^tier: constitutional" "$MEMORY_DIR"/feedback_*.md 2>/dev/null | sort)
|
|
|
|
|
if [ -n "$CONST_FILES" ]; then
|
|
|
|
|
CONST_COUNT=$(echo "$CONST_FILES" | wc -l)
|
|
|
|
|
echo " 📌 헌법급 feedback $CONST_COUNT 건:"
|
|
|
|
|
while IFS= read -r file; do
|
|
|
|
|
[ -f "$file" ] || continue
|
|
|
|
|
name=$(basename "$file" .md)
|
|
|
|
|
desc=$(awk '/^description:/ {sub(/^description: /, ""); print; exit}' "$file" 2>/dev/null | cut -c 1-100)
|
|
|
|
|
echo " • $name"
|
|
|
|
|
[ -n "$desc" ] && echo " → $desc"
|
|
|
|
|
done <<< "$CONST_FILES"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# 0-B. 활성 PD 지시 (개발팀·기획팀 활성 테이블)
|
|
|
|
|
echo ""
|
|
|
|
|
echo " 📋 활성 PD 지시:"
|
|
|
|
|
ACTIVE_LINES=$(grep -h "^| [A-Z0-9]" "$PD_LOG_DIR"/개발팀_PD_지시_로그.md "$PD_LOG_DIR"/기획팀_PD_지시_로그.md 2>/dev/null | grep -E "진행중|대기|보류" | head -10)
|
|
|
|
|
if [ -n "$ACTIVE_LINES" ]; then
|
|
|
|
|
echo "$ACTIVE_LINES" | while IFS= read -r line; do
|
|
|
|
|
id=$(echo "$line" | awk -F'|' '{print $2}' | xargs)
|
|
|
|
|
brief=$(echo "$line" | awk -F'|' '{print $4}' | cut -c 1-90)
|
|
|
|
|
status=$(echo "$line" | awk -F'|' '{print $5}' | xargs)
|
|
|
|
|
echo " • [$id · $status] $brief"
|
|
|
|
|
done
|
|
|
|
|
else
|
|
|
|
|
echo " (활성 지시 없음)"
|
2026-04-18 17:19:21 +00:00
|
|
|
fi
|
|
|
|
|
|
2026-04-22 15:20:06 +00:00
|
|
|
# 0-C. 완료 아카이브 최근 5건
|
|
|
|
|
echo ""
|
|
|
|
|
echo " ✅ PD 지시 완료 아카이브 최근 5건:"
|
|
|
|
|
COMPLETED=$(grep -h "^| [A-Z0-9].*완료" "$PD_LOG_DIR"/개발팀_PD_지시_로그.md "$PD_LOG_DIR"/기획팀_PD_지시_로그.md 2>/dev/null | tail -5)
|
|
|
|
|
if [ -n "$COMPLETED" ]; then
|
|
|
|
|
echo "$COMPLETED" | while IFS= read -r line; do
|
|
|
|
|
id=$(echo "$line" | awk -F'|' '{print $2}' | xargs)
|
|
|
|
|
brief=$(echo "$line" | awk -F'|' '{print $4}' | cut -c 1-90)
|
|
|
|
|
echo " • [$id] $brief"
|
|
|
|
|
done
|
|
|
|
|
else
|
|
|
|
|
echo " (완료 아카이브 없음)"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# 0-D. 최근 7일 기각안 엔트리 (대화로그 "기각안" grep)
|
|
|
|
|
echo ""
|
|
|
|
|
echo " 🚫 최근 7일 기각안 요지:"
|
|
|
|
|
REJECTED=$(find "$DIALOG_DIR" -name "*.md" -mtime -7 -exec grep -l "기각안" {} \; 2>/dev/null | head -5)
|
|
|
|
|
if [ -n "$REJECTED" ]; then
|
|
|
|
|
echo "$REJECTED" | while IFS= read -r file; do
|
|
|
|
|
rel=${file#$REPO_ROOT/}
|
|
|
|
|
count=$(grep -c "^### 기각" "$file" 2>/dev/null || echo 0)
|
|
|
|
|
[ "$count" -gt 0 ] && echo " • $rel — $count 건"
|
|
|
|
|
done
|
|
|
|
|
else
|
|
|
|
|
echo " (최근 7일 기각안 엔트리 없음)"
|
|
|
|
|
fi
|
2026-04-18 17:19:21 +00:00
|
|
|
|
2026-04-22 15:20:06 +00:00
|
|
|
# 0-E. project_context 활성 엔트리 요지 (최신 5개만 미리보기)
|
|
|
|
|
echo ""
|
|
|
|
|
echo " 📚 project_context_조직운영 (최신 5개):"
|
|
|
|
|
CTX_FILE="$MEMORY_DIR/project_context_조직운영.md"
|
|
|
|
|
if [ -f "$CTX_FILE" ]; then
|
|
|
|
|
grep "^- \[" "$CTX_FILE" | head -5 | while IFS= read -r line; do
|
|
|
|
|
echo " $line"
|
|
|
|
|
done
|
|
|
|
|
else
|
|
|
|
|
echo " (파일 없음)"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
echo ""
|
|
|
|
|
|
|
|
|
|
# ─────────────────────────────────────────────────────────────────────
|
|
|
|
|
# 활동 시각 실측 + 공백일수 산정
|
|
|
|
|
# ─────────────────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
# 마지막 commit 시각
|
|
|
|
|
LAST_COMMIT=$(git log -1 --format=%ct 2>/dev/null || echo 0)
|
|
|
|
|
|
|
|
|
|
# 최신 feedback mtime
|
|
|
|
|
LAST_FB=0
|
|
|
|
|
if [ -d "$MEMORY_DIR" ]; then
|
|
|
|
|
LAST_FB=$(find "$MEMORY_DIR" -name "feedback_*.md" -printf '%T@\n' 2>/dev/null | sort -n | tail -1 | cut -d. -f1)
|
|
|
|
|
[ -z "$LAST_FB" ] && LAST_FB=0
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# 최신 대화로그 mtime
|
|
|
|
|
LAST_DL=0
|
|
|
|
|
if [ -d "$DIALOG_DIR" ]; then
|
|
|
|
|
LAST_DL=$(find "$DIALOG_DIR" -name "*.md" -printf '%T@\n' 2>/dev/null | sort -n | tail -1 | cut -d. -f1)
|
|
|
|
|
[ -z "$LAST_DL" ] && LAST_DL=0
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# 최대값
|
|
|
|
|
LAST_ACTIVITY=$LAST_COMMIT
|
|
|
|
|
[ "$LAST_FB" -gt "$LAST_ACTIVITY" ] && LAST_ACTIVITY=$LAST_FB
|
|
|
|
|
[ "$LAST_DL" -gt "$LAST_ACTIVITY" ] && LAST_ACTIVITY=$LAST_DL
|
|
|
|
|
|
|
|
|
|
GAP_SEC=$((NOW - LAST_ACTIVITY))
|
|
|
|
|
GAP_DAYS=$((GAP_SEC / 86400))
|
|
|
|
|
|
|
|
|
|
# ─────────────────────────────────────────────────────────────────────
|
|
|
|
|
# 계층 1~4: 공백일수 기반 동적 윈도우
|
|
|
|
|
# ─────────────────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
# 계층 5 내용축 트리거 감지 (공백 기반 윈도우와 max 채택)
|
|
|
|
|
TRIGGER_WINDOW=0
|
|
|
|
|
TRIGGER_REASONS=""
|
|
|
|
|
|
|
|
|
|
# 인프라 commit 감지 (당일 HEAD 커밋 기준)
|
|
|
|
|
INFRA_CHANGED=$(git log -1 --name-only --format='' 2>/dev/null | grep -E '(\.claude/skills/BurningTimes-코어룰/SKILL\.md|memory/org/feedback_|scripts/.*(hook|ensure|inject|gate|register|archive|sync)|setup/setup_|\.claude/settings|CLAUDE\.md|paths\.local\.json)' | head -1)
|
|
|
|
|
if [ -n "$INFRA_CHANGED" ]; then
|
|
|
|
|
TRIGGER_WINDOW=7
|
|
|
|
|
TRIGGER_REASONS="$TRIGGER_REASONS · 인프라 commit 감지"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# 활성 PD 지시 로그 파일 변경 감지 (최근 1시간)
|
|
|
|
|
PD_LOG_RECENT=$(find "$PD_LOG_DIR" -name "*_로그.md" -mmin -60 2>/dev/null | head -1)
|
|
|
|
|
if [ -n "$PD_LOG_RECENT" ]; then
|
|
|
|
|
[ "$TRIGGER_WINDOW" -lt 7 ] && TRIGGER_WINDOW=7
|
|
|
|
|
TRIGGER_REASONS="$TRIGGER_REASONS · PD 지시 상태 변경"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# 기획 경로 수정 감지 (당일 commit 기준)
|
|
|
|
|
PLAN_CHANGED=$(git log -1 --name-only --format='' 2>/dev/null | grep -E '프로젝트/.*/기획/' | head -1)
|
|
|
|
|
if [ -n "$PLAN_CHANGED" ]; then
|
|
|
|
|
[ "$TRIGGER_WINDOW" -lt 7 ] && TRIGGER_WINDOW=7
|
|
|
|
|
TRIGGER_REASONS="$TRIGGER_REASONS · 기획 경로 수정"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# 시간축 윈도우 결정
|
|
|
|
|
if [ -n "$SESSION_RESTORE_EXTEND" ] && [ "$SESSION_RESTORE_EXTEND" -gt 0 ] 2>/dev/null; then
|
|
|
|
|
WINDOW=$SESSION_RESTORE_EXTEND
|
|
|
|
|
LAYER_TAG="계층 4 · 수동 --extend=$SESSION_RESTORE_EXTEND"
|
|
|
|
|
elif [ "$GAP_DAYS" -le 1 ]; then
|
|
|
|
|
WINDOW=1
|
|
|
|
|
LAYER_TAG="계층 1 · 세션 연속 (공백 ≤1일)"
|
|
|
|
|
elif [ "$GAP_DAYS" -le 7 ]; then
|
|
|
|
|
WINDOW=$GAP_DAYS
|
|
|
|
|
LAYER_TAG="계층 2 · 단기 공백 ($GAP_DAYS일 자동 확장)"
|
|
|
|
|
else
|
|
|
|
|
WINDOW=0
|
|
|
|
|
LAYER_TAG="계층 3 · 장기 공백 (${GAP_DAYS}일) → 전수 탐색 모드"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# 계층 5 max 채택
|
|
|
|
|
if [ "$TRIGGER_WINDOW" -gt "$WINDOW" ]; then
|
|
|
|
|
WINDOW=$TRIGGER_WINDOW
|
|
|
|
|
LAYER_TAG="$LAYER_TAG + 계층 5 ($TRIGGER_WINDOW일$TRIGGER_REASONS)"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
echo "⏱️ [활동 시각] 마지막 활동 ${GAP_DAYS}일 전 · $LAYER_TAG"
|
|
|
|
|
echo ""
|
|
|
|
|
|
|
|
|
|
# ─────────────────────────────────────────────────────────────────────
|
|
|
|
|
# feedback·대화로그 주입
|
|
|
|
|
# ─────────────────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
if [ "$WINDOW" -eq 0 ]; then
|
|
|
|
|
# 계층 3 전수 탐색 모드 — 개수 기반
|
|
|
|
|
echo "🔭 [계층 3 · 전수 탐색] 최근 활동 지점부터 역순 복원:"
|
|
|
|
|
echo ""
|
|
|
|
|
echo " 📘 feedback 최신 10건:"
|
|
|
|
|
find "$MEMORY_DIR" -name "feedback_*.md" -type f -printf '%T@ %p\n' 2>/dev/null | sort -rn | head -10 | awk '{print $2}' | while IFS= read -r file; do
|
|
|
|
|
name=$(basename "$file" .md)
|
|
|
|
|
desc=$(awk '/^description:/ {sub(/^description: /, ""); print; exit}' "$file" 2>/dev/null | cut -c 1-100)
|
|
|
|
|
echo " • $name"
|
|
|
|
|
[ -n "$desc" ] && echo " → $desc"
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
echo ""
|
|
|
|
|
echo " 📝 대화로그 프로젝트당 최신 3건:"
|
|
|
|
|
for proj_dir in "$DIALOG_DIR"/*/; do
|
|
|
|
|
[ -d "$proj_dir" ] || continue
|
|
|
|
|
proj=$(basename "$proj_dir")
|
|
|
|
|
find "$proj_dir" -name "*.md" -type f -printf '%T@ %p\n' 2>/dev/null | sort -rn | head -3 | awk '{print $2}' | while IFS= read -r file; do
|
|
|
|
|
rel=${file#$REPO_ROOT/}
|
|
|
|
|
echo " • $rel"
|
|
|
|
|
done
|
|
|
|
|
done
|
|
|
|
|
else
|
|
|
|
|
# 계층 1·2·4·5 — 기간 기반
|
|
|
|
|
echo "📘 [feedback $WINDOW일 윈도우]:"
|
|
|
|
|
RECENT_FB=$(find "$MEMORY_DIR" -name "feedback_*.md" -mtime -${WINDOW} -type f 2>/dev/null | head -15)
|
|
|
|
|
if [ -n "$RECENT_FB" ]; then
|
|
|
|
|
FB_COUNT=$(echo "$RECENT_FB" | wc -l)
|
|
|
|
|
echo " ($FB_COUNT 건)"
|
|
|
|
|
echo "$RECENT_FB" | while IFS= read -r file; do
|
|
|
|
|
name=$(basename "$file" .md)
|
|
|
|
|
desc=$(awk '/^description:/ {sub(/^description: /, ""); print; exit}' "$file" 2>/dev/null | cut -c 1-100)
|
|
|
|
|
echo " • $name"
|
|
|
|
|
[ -n "$desc" ] && echo " → $desc"
|
|
|
|
|
done
|
|
|
|
|
else
|
|
|
|
|
echo " (해당 윈도우 내 feedback 없음)"
|
2026-04-18 17:19:21 +00:00
|
|
|
fi
|
2026-04-22 15:20:06 +00:00
|
|
|
fi
|
2026-04-18 17:19:21 +00:00
|
|
|
|
2026-04-18 17:26:07 +00:00
|
|
|
echo ""
|
2026-04-22 15:20:06 +00:00
|
|
|
echo "📖 [본문 Read 의무 — C31-G] 의사결정 전 관련 메모리 본문 선행 Read 필수"
|
|
|
|
|
echo " PD님 지시·지적 키워드 매칭 메모리·헌법급 feedback은 계층 0에서 이미 환기됨"
|
|
|
|
|
echo " 상세: memory/org/feedback_session_restore_monitoring.md (6계층 운영 모니터링 SOT)"
|
2026-04-18 17:26:07 +00:00
|
|
|
|
2026-04-18 17:19:21 +00:00
|
|
|
exit 0
|