Alert Triage Protocol
Purpose: #pantheon-alerts에 수신된 알림을 신속하게 분류하고, 적절한 수준의 조치를 자동으로 실행하는 운영 절차를 정의한다.
Scope: log_monitor-alert, Slack #pantheon-alerts, Asurada 트리아지 역할
파이프라인
bridge.log (ERROR/WARN)
→ log_monitor 감지
→ #pantheon-alerts 알림 (Jarvis)
→ Asurada @멘션 → 트리아지
→ Slack 보고 (+ real problem이면 hangman-docs 상세 보고서)
→ Linear 이슈 코멘트 또는 신규 이슈
분류 기준
| 분류 | 정의 | 기본 조치 |
|---|---|---|
| noise | 단발성, 자동 복구 가능, 기능 영향 없음 | Linear 코멘트 기록, 이슈 조치 없음 |
| real problem | 재현 가능, 반복 패턴, 명확한 기능 영향 | 기존 이슈 격상 또는 신규 이슈 생성 + 해결 |
| unsure | 데이터 불충분, 판단 불가 | 사용자에게 확인 질문 |
noise 판별 신호
- 단일 로그 라인, 연속 발생 없음
- INFO / DEBUG 레벨 (ERROR라도 예상 범위 내 transient이면 noise 가능)
- 이미 알려진 이슈 (Linear 이슈 In Progress 상태)
- 자동 재시도로 복구된 것으로 추정 (후속 오류 없음)
- 환경 일시 장애: 네트워크 timeout, IncompleteRead, SSL handshake timeout
Slack API 네트워크 오류 (알려진 noise 패턴)
| 오류 유형 | 발생 지점 | 기본 판정 |
|---|---|---|
IncompleteRead |
응답 수신 중 연결 끊김 | noise |
SSL handshake timed out |
연결 수립 단계 timeout | noise |
ConnectionResetError |
TCP 연결 강제 종료 | noise |
단, 동일 유형이 30분 내 3회+ 발생하면 real로 격상.
real problem 판별 신호
- 동일 오류 연속 3회 이상
- 30분 이내 cluster 2회+ (다른 유형이라도 동일 컴포넌트)
- 기능 영향 확인: 메시지 미전달, 명령 실패, 파이프라인 중단
- 새로운 미확인 오류 유형 (기존 패턴 목록에 없음)
- 스택트레이스에 내부 로직 오류 포함 (네트워크 레이어 외부)
격상 규칙
noise 기본 판정
→ 동일 컴포넌트 30분 내 3회+ 재발
→ real problem으로 격상
→ Linear 이슈 우선순위 상향 + 즉시 해결 착수
로그 레벨 조정 기준
원인 진단 결과 코드 내 log level이 실제 심각도와 불일치하면 소스 수정을 권장한다.
레벨 조정은 기능 fix와 별개 항목으로 해결 방안에 추가한다.
ERROR 유지 조건
- 기능 miss 발생 (메시지 미전달, 파이프라인 중단, 데이터 손실)
- retry 후에도 실패하는 경우
- 내부 로직 오류 (네트워크 레이어 외부 — 예: KeyError, AttributeError)
- 수동 개입 없이 자동 복구 불가
ERROR → WARNING 격하 조건
- 기능 영향 없음 + 자동 복구 가능 (silent degradation)
- 알려진 외부 한계: Slack API 간헐적 drop, 네트워크 transient 오류
- retry / 재스캔으로 자동 보완되는 패턴
- 발생 빈도가 예측 가능하고 운영 노이즈 수준
WARNING → INFO 격하 조건
- 정상 동작의 부산물 (채널 스캔 스킵, rate limit 준수 대기)
- 알려진 Slack API 한계 내 동작 (IncompleteRead, 대형 응답 drop)
- log_monitor 필터 대상에 포함되어서는 안 되는 일상 이벤트
소스 수정 절차
- 원인 진단에서 로그 레벨 불일치 확인
- 해결 방안에 레벨 조정 옵션을 기능 fix와 별개 항목으로 추가
- real problem 보고서 "소스 수정 권장" 섹션에 기재
- Linear 이슈 코멘트에 레벨 조정 여부 명시
조치별 절차
noise
- 기존 Linear 이슈 있으면:
save_comment로 발생 기록 추가 - 기존 이슈 없으면: 기록하지 않음 (단발성 노이즈는 이슈 생성 금지)
- Slack 스레드에 트리아지 결과 회신 (Slack 보고 양식 — noise 버전)
real problem
- 기존 이슈 있으면: 코멘트 + 우선순위 격상 검토
- 기존 이슈 없으면: Triage 블록 출력 후 신규 이슈 생성
- hangman-docs 상세 보고서 작성 + 배포 (아래 워크플로우 참조)
- Slack 스레드에 트리아지 결과 + 상세 보고서 링크 회신
- 해결 착수
unsure
- 사용자에게 한 줄로 확인 질문
- 확인 전까지 이슈 생성 보류
Triage 블록 (신규 이슈 생성 직전 필수 출력)
[Triage]
- 문제/노이즈: real problem | noise | unsure
- 우선순위: Urgent/High/Medium/Low — 근거 1줄
- 중복 확인: 검색 keyword + 결과
- 위임 중복 위험: follow-up 책임자 명시됨? (yes/no)
Slack 보고 양식
트리아지 결과를 Slack 스레드에 회신할 때 사용하는 포맷.
noise/real problem에 따라 분량을 조절하되, 섹션 순서는 고정한다.
noise 버전 (3줄 이내)
[noise] {오류 유형} — {판정 근거 1줄}
발생: {횟수}회 / {시간대} / {컴포넌트}
조치: {없음 | Linear #{N} 코멘트 추가}
예시:
[noise] IncompleteRead — 단발성, 후속 오류 없음, 알려진 Slack 네트워크 패턴
발생: 1회 / 17:20 / mention-proxy
조치: 없음 (noise 단발성 — 이슈 불필요)
real problem 버전 (섹션 4개 필수)
[{분류}] {HAN-N} {제목}
[에러 신호]
• 로그 원문 (핵심 라인만)
• 발생 패턴: {횟수}회 / {시간 범위} / {채널·컴포넌트}
[분류 근거]
• real problem: {근거} (예: 30분 내 4회 cluster, 기능 영향 확인)
• noise로 보지 않은 이유: {이유}
• 검토 후 기각한 가설: {가설} → {기각 근거}
[원인 진단]
{로그 위치} → {코드 파일:라인} → {동작 설명} → {실패 조건}
예) conversations_history(limit=100) [audit.py:196] → retry 없음
→ 대용량 응답(~273KB)에서 Slack이 TCP drop
→ IncompleteRead 예외 → mention miss
[해결 방안]
• 옵션 A: {설명} — tradeoff: {트레이드오프}
• 옵션 B: {설명} — tradeoff: {트레이드오프}
권장: {A|B} — {이유 1줄}
[소스 수정 권장] (로그 레벨 조정 대상인 경우만)
• 현재 레벨: {ERROR|WARNING} → 권장 레벨: {WARNING|INFO}
• 근거: {격하 조건 해당 항목}
상세 보고서: {hangman-docs.pages.dev/... URL}
Linear: {HAN-N URL}
hangman-docs 상세 보고서 워크플로우
real problem 판정 시 아래 흐름으로 상세 보고서를 작성하고 Cloudflare 링크를 공유한다.
1. worktree 생성
git -C ~/Workspace/hangman-docs worktree add \
../hangman-docs-{ISSUE} -b docs/{ISSUE}
2. 보고서 작성
파일: reports/{ISSUE}-triage.md
포맷: 아래 보고서 템플릿 참조
3. HTML 렌더링
cd ~/Workspace/hangman-docs-{ISSUE}
_templates/render.sh reports/{ISSUE}-triage.md
4. 커밋 + PR
git add reports/{ISSUE}-triage.md reports/{ISSUE}-triage.html
git commit -m "reports: add {ISSUE} triage report"
git log --oneline origin/main..HEAD # 커밋 확인
git push -u origin docs/{ISSUE}
gh pr create --title "{ISSUE} triage report" --body "..."
gh pr merge {N} --squash
5. 배포 확인 + 링크 공유
URL: https://hangman-docs.pages.dev/reports/{ISSUE}-triage.html
curl -s -o /dev/null -w "%{http_code}" {URL} # 200 확인
Slack 스레드에 URL 회신
6. worktree 정리
git worktree remove ~/Workspace/hangman-docs-{ISSUE} --force
git branch -D docs/{ISSUE}
git push origin --delete docs/{ISSUE}
hangman-docs 보고서 템플릿
reports/{ISSUE}-triage.md 작성 시 사용하는 기본 구조.
---
type: report
subtype: result
issue: HAN-N
date: YYYY-MM-DD
author: asurada
status: final
---
# [HAN-N] {제목}
## 에러 신호
로그 원문 (핵심 라인만)과 발생 패턴 (타임스탬프, 채널, 컴포넌트, 횟수).
## 분류 근거
- **판정**: real problem / noise / unsure
- **real 근거**: ...
- **noise 기각 이유**: ...
- **검토·기각 가설**: {가설} → {기각 근거}
## 원인 진단
{로그 위치} → {코드 파일:라인} → {동작 설명}
→ {실패 조건} → {사용자 영향}
## 해결 방안
| 옵션 | 설명 | tradeoff |
|------|------|----------|
| A | ... | ... |
| B | ... | ... |
**권장**: A — {이유 1줄}
## 소스 수정 권장
로그 레벨 조정이 필요한 경우만 기재한다. 불필요하면 섹션 생략.
- **현재 레벨**: {ERROR|WARNING}
- **권장 레벨**: {WARNING|INFO}
- **근거**: {격하 조건 해당 항목}
- **대상 파일:라인**: {file.py:N}
## 조치 결과
- Linear: {HAN-N URL}
- PR: {PR URL if any}
- 해결 여부: 완료 / 진행 중 / 사용자 결정 대기
운영 원칙
- 코멘트 추가가 기본 반응이 아니다. noise 단발성은 기록조차 생략 가능.
- 이슈 생성 = 조치 의도 표명. 의도 없으면 생성 금지.
- 판단 근거는 반드시 노출한다. 결론만 있는 보고는 검증 불가.
- real problem은 hangman-docs 상세 보고서를 통해 추론 체인을 공개한다.
- 판정 결과는 항상 Slack 스레드에 회신해 가시성 확보.
- 격상 트리거를 명시적으로 정의해 주관적 판단 최소화.