Playball Logo

Command Palette

Search for a command to run...

목차 열기

06. Analyzer — 규칙 기반 증거 축적

Guard가 연속적인 숫자 기반 점수 계산을 담당한다면, Analyzer는 짧은 시간 내 특정 패턴의 반복을 규칙 기반으로 감지합니다.

파생 신호 3가지

신호감지 조건기본 임계의미
rapid_high_value_click1.5초 윈도우 안에 좌석 클릭/확보 N회 이상3회대량 선점 시도
excessive_read_scanning2초 윈도우 안에 조회 API N회 이상8회자동화 스캐닝 (정상 사용자는 초당 1~2회)
s3_fail_burst60초 안에 챌린지 N회 이상 실패2회챌린지 연속 실패 (정상은 대개 1회 내 통과)

Redis Bucket Counter 메커니즘

구조

key = tm:session:{sessionId}:counter:{signal_type}:{bucket_index}
bucket_index = ts_ms // window_ms
operation = INCR
TTL = window_seconds + 2초

동작

  • 현재 시간의 bucket index로 키 생성
  • INCR 하나로 카운트 증가
  • 윈도우가 지나면 TTL로 자동 만료
  • 슬라이딩 윈도우가 아닌 고정 bucket — O(1) 연산

왜 고정 bucket인가

방식특성
슬라이딩 윈도우정확하지만 매 요청마다 타임스탬프 정렬 비용
고정 bucket약간 부정확하지만 O(1), Runtime 경로 부담 없음

세션 상태 필드

Analyzer가 관리하는 상태 필드들입니다.

필드의미증가 조건리셋 조건
challengeFailCount챌린지 실패 누적S3 FAILS3 PASS (0으로)
seatTakenStreakHold 성공 연속/api/hold 2xx 또는 HIGH_VALUE_CLICK.holdResult=SUCCESSHold 실패 (0으로)
holdFailStreakHold 실패 연속/api/hold 4xx 또는 holdResult=FAILHold 성공 (0으로)
probationUntilMs보호 대기 만료 시각S3 PASS 시 now + probation_seconds 설정
challengeHaltUntilMs챌린지 임시 잠금 만료재시도 max attempts 초과

책임 경계

Analyzer가 쓸 수 있는 필드는 위 5개로 엄격히 제한됩니다.

컴포넌트쓸 수 있는 필드
GuardriskScore, defenseTier, lastStepRisk, lastGuardTsMs
AnalyzerchallengeFailCount, seatTakenStreak, holdFailStreak, probationUntilMs, challengeHaltUntilMs
OrchestratorflowState, s3Passed, s3PassedAtMs, lastDecisionAction

왜 엄격히 분리 — 한 컴포넌트의 버그가 다른 컴포넌트 상태를 오염시킬 위험 최소화. 운영 중 상태가 이상해도 원인 파악이 빠름.

이벤트 타입별 처리

HIGH_VALUE_CLICK

페이로드처리
holdResult: SUCCESSseatTakenStreak += 1, holdFailStreak = 0
holdResult: FAILholdFailStreak += 1, seatTakenStreak = 0
모든 경우rapid_high_value_click 버킷 카운터 증가

API_CALL_OBS

조건처리
메서드 READ 또는 GETexcessive_read_scanning 버킷 카운터 증가
/api/hold 계열 + statusCode >= 400holdFailStreak += 1
/api/hold 계열 + statusCode < 300seatTakenStreak += 1

S3_RESULT

페이로드처리
PASSchallengeFailCount = 0, probationUntilMs 설정
FAILchallengeFailCount += 1, s3_fail_burst 버킷 증가

Evidence Summary (Planner 입력)

Analyzer가 갱신한 정보를 Planner에 전달하는 형태입니다.

압력 지표 (LOW/MED/HIGH)

지표계산
scan_pressureexcessive_read_scanning 카운터 ÷ 임계값
hv_click_pressurerapid_high_value_click 카운터 ÷ 임계값
구간의미
임계값 미만LOW
임계값 이상~2배 미만MED
임계값 2배 이상HIGH

Rule Hits (파생 신호 활성 플래그)

플래그조건
RAPID_HIGH_VALUE_CLICK신호 임계 초과
EXCESSIVE_READ_SCANNING신호 임계 초과
S3_FAIL_BURST신호 임계 초과

감사 이벤트

DEF_ANALYZER_EVIDENCE_UPDATED 이벤트로 기록:

필드의미
countersSnapshot현재 카운터 스냅샷
rapidHVClick신호 활성 여부
excessiveReadScanning신호 활성 여부
s3FailBurst신호 활성 여부
scanPressureLOW/MED/HIGH
hvClickPressureLOW/MED/HIGH
challengeFailCount현재값
seatTakenStreak현재값
holdFailStreak현재값

기본 임계값 (정책에서 변경 가능)

신호윈도우임계
rapid_high_value_click1500 ms3
excessive_read_scanning2000 ms8
s3_fail_burst60000 ms2

Planner에서 어떻게 쓰이나

규칙 위반은 Action을 직접 바꾸지 않고 reason suffix로 반영됩니다.

시나리오TierActionReason
정상T0NONEtier=T0
스캐닝 집중T1THROTTLEtier=T1, scan_high
고가치 클릭 연속 + 스캐닝T2THROTTLEtier=T2, hv_high, scan_high
챌린지 연속 실패 + T3T3BLOCKtier=T3, s3_fail_burst

참조