I1: collect_status - heartbeat 키 존재 여부가 아닌 ts age 기반으로 alive 판정.
age > NODE_STALE_THRESHOLD_SEC(90s, env 주입 가능)이면 키 있어도 dead.
config.py에 NODE_STALE_THRESHOLD_SEC=90 추가.
I2: check_and_alert - 다운/복구 전이 시 send_raw 실패하면 _node_state 갱신 보류.
다음 사이클에서 동일 전이 재감지 → 재발송 시도 (다운 이벤트 유실 방지).
테스트: _hb 헬퍼 현재 시각 기본값으로 수정 + 신규 2개 (stale→dead, I2 재시도 회귀).
14 passed.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019LV86jBozkNhSFXJA412fq
- _dl_notified[name] = dl을 if ok: 블록 안으로 이동 — 텔레그램 실패 시 갱신 방지
- check_and_alert에 collect_status try/except 추가 — 스케줄러 잡 생존 보장
- tests: import app.node_monitor as nm 최상단 이동
- tests: test_dl_notified_not_updated_on_telegram_failure 회귀 테스트 추가
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019LV86jBozkNhSFXJA412fq
- per-worker 루프 전체를 try/except로 감싸 Redis 예외 시 redis_ok=False+break (Blocker)
- heartbeat 파싱 except에 UnicodeDecodeError 추가 (Important)
- hb.get('ts') or '' 로 null ts 안전 처리 (Minor)
- 테스트 3개 추가: paused 폴백·processing 집계·llen 예외 회귀
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019LV86jBozkNhSFXJA412fq
에이전트 레지스트리가 2→7로 늘어 len==2/{stock,music} 고정 단언이 stale였음. 핵심 시드 subset 검증으로 변경(레지스트리 확장에 견고). 이번 세션 audit에서 반복 플래그된 부채.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
결함1: deep signal-check에서 curate_weekly가 CuratorError면 전체 check가 abort돼 sim/drift 시그널이 미평가되던 문제 → try/except로 confidence만 포기하고 sim/drift는 계속(curate_result=None fallthrough).
결함2: send_urgent_signal 실패가 outer except로 빠져 task 실패+미마킹이던 문제 → _send_urgent_with_retry(3회/60s) 추출, 최종 실패해도 raise 안 함(시그널 평가·태스크 보존), 성공 시에만 mark_signal_notified. TDD 3 신규 테스트.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
504 Gateway Timeout 근본 원인은 DSM Reverse Proxy의 60s 기본 timeout
(agent-office는 200 OK 정상 응답했으나 client 도달 전 DSM이 끊음).
사용자 측 DSM Reverse Proxy timeout 늘리기 별도 필요.
코드 측 대응:
- pipeline.py max_tokens 2048 → 1400 (응답 시간 단축, 3-card spread 충분)
- pipeline.py에 latency_ms·tokens 로그 출력 (모니터링)
- nginx /api/agent-office/에 proxy_send_timeout 300s, proxy_connect_timeout 60s
추가 (proxy_read_timeout은 WebSocket 위해 86400s 유지)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
_dedup_and_filter_keywords: score>=0.7만 남기고 동일 keyword 중복 제거
(최고 score 유지) 후 내림차순. _push_keyword_candidates가 이 필터를 거쳐
"확실한 것만" 전송, 후보 없으면 안내 메시지. 헬퍼 테스트 5건.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- weight_evolver.evaluate_weekly: save_base_history 직전에 current_base를
previous_base로 캡처해 return dict에 포함 → formatter가 진짜 diff 표시 가능
- evaluate_weekly: same effective_from row 이미 존재 시 save skip + idempotent
return (토 22:00 lotto cron과 agent-office 22:15 재호출 중복 row 방지)
- main._run_weight_evolver_daily: 일요일(weekday=6) 도 skip — 토요일 trial을
INSERT OR REPLACE로 덮어쓰는 문제 방지
- telegram_lotto._format_evolution_report: eval_result.previous_base 우선
사용 (없으면 current_base 폴백) → diff 자기 자신 비교 버그 수정
- test_lotto_evolution_format: previous_base 키 추가 + 새 diff 검증 테스트
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>