"""Expose frozen historical network alarms without implying a live validated feed.""" import datetime as dt import json import math from pathlib import Path from zoneinfo import ZoneInfo from .network_review import aware_time DATA=Path(__file__).with_name('data')/'network_monitor_research.json' def load_bundle(): if not DATA.exists():return {'state':'research_monitor_not_installed'} return json.loads(DATA.read_text(encoding='utf-8')) def watch_signal(bundle,date,cutoff): instant=aware_time(cutoff) if instant is None:raise ValueError('cutoff requires a timezone-aware timestamp') requested=dt.date.fromisoformat(date) if bundle.get('state')!='research_evaluation_available':return {'state':'research_monitor_not_installed'} local_day=instant.astimezone(ZoneInfo('Asia/Seoul')).date() if (local_day-requested).days>1: return {'state':'stale_research_date_for_cutoff','date':date,'cutoff_utc':instant.isoformat()} if requested<=dt.date.fromisoformat(bundle['training_end']): return {'state':'calibration_not_available_before_signal','date':date,'training_end':bundle['training_end']} available=aware_time(date+'T23:59:59+09:00') if available>instant:return {'state':'unclosed_or_unavailable_session','date':date} observations=bundle['observations'] if date not in observations: return {'state':'research_date_unavailable','date':date,'available_start':min(observations,default=None), 'available_end':max(observations,default=None)} row=observations[date] score=row.get('score');cut=bundle.get('model',{}).get('cut') if (bundle.get('model',{}).get('state')!='fitted' or not isinstance(row.get('original_alert'),bool) or score is None or cut is None or not math.isfinite(float(score)) or not math.isfinite(float(cut))): return {'state':'insufficient_network_data','date':date,'score':None,'research_only':True} return dict(state='research_alert' if row['original_alert'] else 'no_research_alert',date=date, cutoff_utc=instant.isoformat(),available_by_assumption=available.isoformat(), primary_rule=bundle['primary_rule'],training_end=bundle['training_end'], market_scope=bundle.get('market_scope','Original fixed Korean-equity research sample'), available_snapshot_dates=bundle.get('available_snapshot_dates',[]), score=float(score),frozen_cut=float(cut),above_frozen_cut=float(score)>=float(cut), original_alert=row['original_alert'],equal_token_capacity_alert=row.get('equal_token_capacity_alert'), baseline_alerts=row.get('baseline_alerts',{}),research_only=True,live_monitor=False, validated_detection_or_forecast_superiority=False, comparison_findings=bundle.get('comparison_findings',{}), historical_membership_and_release_vintages_verified=False, interpretation='Fixed original-research historical rule; an alert is a model threshold event, not proof of an abnormal regime, future loss or causation.')