# QA-2 Report — Persona Forget Algorithm Verification > Worker: Explore agent (ultrathink) · Lead review: 승인 ## Summary - **verdict**: APPROVE - critical: 0, major: 0, minor: 2 ## 상수 검증 | Constant | Expected | Actual | OK? | |---|---|---|---| | PERSONA_LAMBDA.senior | 0.1 | 0.1 | ✓ | | PERSONA_LAMBDA.mid | 0.2 | 0.2 | ✓ | | PERSONA_LAMBDA.junior | 0.4 | 0.4 | ✓ | | PERSONA_LAMBDA.crammer | 0.6 | 0.6 | ✓ | | INTENSITY_THRESHOLD.strict | 0.7 | 0.7 | ✓ | | INTENSITY_THRESHOLD.moderate | 0.5 | 0.5 | ✓ | | INTENSITY_THRESHOLD.relaxed | 0.35 | 0.35 | ✓ | | DEFAULT_K | 4.0 | 4.0 | ✓ | | DEFAULT_INITIAL_S0 | 0.3 | 0.3 | ✓ | | MAX_INTERVAL_DAYS | 60 | 60 | ✓ | ## 수식 유도 검증 **목표**: σ(k·(S₀·e^(-λt) - D)) = P_threshold 를 t에 대해 풀기. 1. σ⁻¹ 적용: `k·(S₀·e^(-λt) - D) = logit(P_threshold)` 2. `S₀·e^(-λt) = D + logit(P_threshold)/k` (== target) 3. `e^(-λt) = target / S₀` 4. `t = -(1/λ)·ln(target / S₀)` 코드(`persona-forget.service.ts:131`): ```ts const tDays = -(1 / lambda) * Math.log(target / s0); ``` **✓ 수식과 코드가 정확히 일치.** ## 경계 조건 검증 | Case | 예상 동작 | 코드 경로 | OK? | |---|---|---|---| | s0 ≤ 0 | 즉시 (1h) 스케줄 | 103-109 | ✓ | | target ≤ 0 | 60일 cap | 114-120 | ✓ | | target ≥ s0 | ln ≤ 0 → t ≤ 0 → 즉시 | 122-128 | ✓ | | 0 < target < s0 | 정상 공식 | 131 | ✓ | | t > 60 | `Math.min(tDays, MAX_INTERVAL_DAYS)` | 132 | ✓ | | logit(0) / logit(1) | ε clamp | 192 | ✓ | | predictP at t=0 | σ(k(s0 - D)) | 150-153 | ✓ | 모든 경계 조건에서 수학적 domain error 없음. ## updateS0 검증 | prev | result | formula | expected | OK? | |---|---|---|---|---| | 0.2 | correct | 0.2·0.5+0.6 | 0.70 | ✓ | | 1.0 | correct | clamp(1.1) | 1.0 | ✓ | | 0.8 | incorrect | 0.8·0.5 | 0.40 | ✓ | | 0.4 | partial | 0.4·0.7+0.3 | 0.58 | ✓ | | null | correct | 0.3·0.5+0.6 | 0.75 | ✓ (기본값 0.3에서 시작) | ## Findings ### [minor] 스펙 커버리지 — persona × intensity matrix 불완전 - **Location**: `backend/src/forget/persona-forget.service.spec.ts:40-130` - **Evidence**: senior vs crammer 비교, 3개 intensity 개별 테스트는 있지만 4 persona × 3 intensity = 12 조합을 grid로 돌리는 테스트가 없음. - **Impact**: 공식상 persona/intensity는 단순 lookup이라 회귀 가능성 낮음. 다만 CI 신뢰도 측면에서 보완 권장. - **Suggested fix**: `describe.each([...])` 로 matrix 테스트 추가. ### [minor] study-logs / reviews 에서 `lastUpdatedAt: new Date()` 중복 생성 - **Location**: `backend/src/study-logs/study-logs.service.ts:96, 115`, `backend/src/reviews/reviews.service.ts:87, 106` - **Evidence**: snapshot upsert 와 schedule() 호출이 각각 `new Date()`를 독립 생성. 수 ms 차이 발생 가능. - **Impact**: 스케줄 시각이 수 ms 어긋남. 무시 가능 수준이지만 의미가 모호해짐. - **Suggested fix**: `const now = new Date()` 를 함수 진입부에서 한 번만 생성. ## Verdict **APPROVE**. 알고리즘의 수식·경계·consumer 호출 모두 정확. minor 2건만 follow-up 개선 권장.