date('Y-m-d H:i:s', $now - $secAgo); $LEAK = SMS_TAG_LEAK_ALERT; $LEAK_R = SMS_TAG_LEAK_RECOVERY; $HITEMP = SMS_TAG_HIGH_TEMP; $METRIC_R = SMS_TAG_RECOVERY; $body = fn(string $tag): string => $tag . "\n위치: 시험\n센서: t"; // ── 1) 이력 없음 → 발송(생략 아님) ────────────────────────── check(alert_cooldown_suppresses(null, null, $LEAK, $COOL, $now) === false, 'no history -> send (not suppressed)'); // ── 2) 지속 누수: 최신이 [누수감지] & 쿨다운 이내 → 생략 ───── check(alert_cooldown_suppresses($body($LEAK), $at(60), $LEAK, $COOL, $now) === true, 'ongoing leak within cooldown -> suppress (flood guard kept)'); // ── 3) 오래된 누수: 최신이 [누수감지] & 쿨다운 경과 → 발송 ─── check(alert_cooldown_suppresses($body($LEAK), $at(3600), $LEAK, $COOL, $now) === false, 'stale leak beyond cooldown -> send (periodic re-alert)'); // ── 4) [핵심 버그] 복구 직후 재발: 최신이 [누수복구] → 발송 ── // 복구가 방금(1초 전) 있었어도, 새 누수는 별개 에피소드이므로 쿨다운 무시하고 발송해야 한다. check(alert_cooldown_suppresses($body($LEAK_R), $at(1), $LEAK, $COOL, $now) === false, 'BUG REGRESSION: leak right after [누수복구] -> send (must NOT be suppressed)'); // ── 5) 경계값: elapsed == cooldown 은 생략 아님(< 비교) ────── check(alert_cooldown_suppresses($body($LEAK), $at($COOL), $LEAK, $COOL, $now) === false, 'elapsed exactly == cooldown -> send (strict <)'); check(alert_cooldown_suppresses($body($LEAK), $at($COOL - 1), $LEAK, $COOL, $now) === true, 'elapsed cooldown-1 -> suppress'); // ── 6) 온습도 경보도 동일: 최신이 [정상복귀] → 발송 ───────── check(alert_cooldown_suppresses($body($METRIC_R), $at(1), $HITEMP, $COOL, $now) === false, 'metric: high_temp right after [정상복귀] -> send (episode reset)'); // 지속 고온: 최신이 [고온경보] & 이내 → 생략 check(alert_cooldown_suppresses($body($HITEMP), $at(60), $HITEMP, $COOL, $now) === true, 'metric: ongoing high_temp within cooldown -> suppress'); // ── 7) 다른 종류 경보가 최신이면 이 종류 쿨다운에 안 걸림 ──── // (쿼리도 이 종류+복구만 뽑지만, 순수함수는 prefix 로 방어) check(alert_cooldown_suppresses($body(SMS_TAG_HIGH_HUMIDITY), $at(60), $HITEMP, $COOL, $now) === false, 'metric: latest is different-kind alert -> this kind not suppressed'); if ($failures) { fwrite(STDERR, "Cooldown episode test failures:\n"); foreach ($failures as $f) { fwrite(STDERR, "- {$f}\n"); } exit(1); } echo "Cooldown episode-aware checks passed.\n";