7ab6baeed2
fix(prediction): stats_aggregator hour 경계 silent 누락 복구
...
배경: prediction 5분 interval 이지만 한 사이클 평균 13분 소요라
사이클이 hour 경계를 넘나드는 경우(12:55 시작 → 13:08 완료)가 흔하다.
이 때 사이클 내 생성된 이벤트(occurred_at=12:57)가 aggregate_hourly
호출 시점(now_kst=13:08) 기준 현재 hour=13:00 만 UPSERT 되어
12:00 hour 는 이전 사이클 snapshot 으로 stale 유지되는 silent drop.
실제 포착: 2026-04-20 12:50 CRITICAL GEAR_IDENTITY_COLLISION 이벤트가
prediction_stats_hourly.by_category 12:00 slot 에서 누락. Phase 1-2
snapshot 의 C1 drift 섹션이 only_in_events=GEAR_IDENTITY_COLLISION 으로 탐지.
수정:
- _aggregate_one_hour(conn, hour_start, updated_at): 단일 hour UPSERT 추출
- aggregate_hourly(): 호출 시마다 previous→current 순서로 2번 집계
· UPSERT 라 idempotent
· 반환값은 현재 hour (하위 호환)
· target_hour 지정 케이스도 ±1h 재집계
검증:
- 3 유닛테스트 (경계 호출 2건 / 반환값 / 일 경계) 전수 통과
- 운영 수동 재집계로 12:00 slot GEAR_IDENTITY_COLLISION: 1 복구
- snapshot 재실행 시 C1 drift 0 확인
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 13:32:44 +09:00
8f5152fc02
feat(prediction): Phase 2 PoC 2~5 — gear_violation/transshipment/risk/pair_trawl
...
런타임 override 완성 (params 인자 + 내부 상수 교체):
- gear_violation_g01_g06 (GEAR, tier 4)
· G01~G06 점수 + signal_cycling(gap_min/min_count)
· gear_drift_threshold_nm + fixed_gear_types + fishery_code_allowed_gear
· _detect_signal_cycling_count 도입 (기존 _detect_signal_cycling 보존)
카탈로그 + 관찰 (DEFAULT_PARAMS 노출 + Adapter 집계, 런타임 교체는 후속 PR):
- transshipment_5stage (TRANSSHIP, tier 4) — 5단계 필터 임계
- risk_composite (META, tier 3) — 경량+파이프라인 가중치
- pair_trawl_tier (GEAR, tier 4) — STRONG/PROBABLE/SUSPECT 임계
각 모델 공통:
- prediction/algorithms/*.py: DEFAULT_PARAMS 상수 추가
- models_core/registered/*_model.py: BaseDetectionModel Adapter
- models_core/seeds/v1_<model>.sql: DRAFT seed (호출자 트랜잭션 제어)
- tests/test_<model>_params.py: Python ↔ 모듈 상수 ↔ seed SQL 정적 일치 검증
통합 seed: models_core/seeds/v1_phase2_all.sql (\i 로 5 모델 일괄 시드)
검증:
- 30/30 테스트 통과 (Phase 1-2 15 + dark 5 + Phase 2 신규 10)
- 운영 DB 5 모델 개별 + 일괄 seed dry-run 통과 (BEGIN/ROLLBACK 격리)
- 5 모델 모두 tier/category 정렬 확인: dark_suspicion(3) / risk_composite(3) /
gear_violation_g01_g06(4) / pair_trawl_tier(4) / transshipment_5stage(4)
후속:
- transshipment/risk/pair_trawl 런타임 override 활성화 (헬퍼 params 전파)
- Phase 3 백엔드 API (DetectionModelController + 승격 엔드포인트)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 10:11:16 +09:00
8c586c3384
feat(prediction): Phase 2 PoC #1 — dark_suspicion 모델 외부화
...
- algorithms/dark_vessel.py: compute_dark_suspicion 에 params 인자 추가
· DARK_SUSPICION_DEFAULT_PARAMS 상수(19 가중치 + SOG/반복/gap/tier 임계)
· _merge_default_params 깊이 병합 — params=None 시 BACK-COMPAT 완전 보장
· override 가 DEFAULT 를 변조하지 않는 불변성
- models_core/registered/dark_suspicion_model.py: BaseDetectionModel Adapter
· AnalysisResult 리스트에서 gap_info 재평가
· evaluated/critical/high/watch_count 메트릭 기록
- models_core/seeds/v1_dark_suspicion.sql: DRAFT seed (운영 영향 0)
· BEGIN/COMMIT 미포함 — 호출자 트랜잭션 제어 (psql -1 또는 wrap)
· JSONB params 는 Python DEFAULT 와 1:1 일치
- models_core/seeds/README.md: 실행·승격 절차, 금지 패턴, 롤백
- tests/test_dark_suspicion_params.py: 5건 동치성 검증
· DEFAULT 형태, None↔DEFAULT 동치성, override 불변성
· seed SQL JSONB ↔ Python DEFAULT 정적 일치 검증
- 전체 20/20 테스트 통과 (Phase 1-2 기반 15 + Phase 2-1 동치성 5)
- seed SQL 운영 DB dry-run(BEGIN/ROLLBACK) 성공 — INSERT 2건 정상, tier_thresholds 일치 확인
후속: gear_violation_g01_g06 / transshipment_5stage / risk_composite / pair_trawl_tier
는 별도 PR. 각 모델 같은 패턴(params 인자 + DEFAULT 상수 + Adapter + seed).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 08:19:57 +09:00
2ceeb966d8
feat(prediction): Phase 1-2 detection model registry + snapshot 관찰 보강
...
- models_core 패키지 신설 — BaseDetectionModel / ModelContext / ModelResult
+ Registry (ACTIVE 버전 인스턴스화, DAG 순환 검출, topo 플랜)
+ DAGExecutor (PRIMARY→ctx.shared 주입, SHADOW persist-only 오염 차단)
+ params_loader (5분 TTL 캐시), feature_flag (PREDICTION_USE_MODEL_REGISTRY)
- V034 스키마 정합성 사전 검증 + silent error 3건 선제 방어
· model_id VARCHAR(64) 초과 시 __init__ 에서 즉시 ValueError
· metric_key VARCHAR(64) 초과는 경고 후 drop (다른 metric 는 저장)
· persist 가 ctx.conn 재사용 (pool maxconn=5 고갈 방지)
- scheduler.py — 10단계 feature flag 분기 (기본 0, 구 경로 보존)
- partition_manager — detection_model_run_outputs 월별 파티션 자동 생성/DROP
- 유닛테스트 15 케이스 전체 통과 (DAG 순환, SHADOW 오염 차단, 길이 검증)
- snapshot 스크립트 (hourly/diagnostic) 개선
· spoofing gt0/gt03/gt05/gt07 세분화 — 'silent fault' vs 'no signal' 구분
· V030 gear_identity_collisions 원시 섹션 (CRITICAL 51건 OPEN 포착)
· V034 detection_model_* 모니터링 섹션 (Phase 2 대비)
· stage timing 집계 + stats_hourly vs events category drift 감시
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 08:07:29 +09:00
e2fc355b2c
feat: S2 prediction 분석 엔진 모노레포 이식
...
iran prediction 47개 Python 파일을 prediction/ 디렉토리로 복제:
- algorithms/ 14개 분석 알고리즘 (어구추론, 다크베셀, 스푸핑, 환적, 위험도 등)
- pipeline/ 7단계 분류 파이프라인
- cache/vessel_store (24h 슬라이딩 윈도우)
- db/ 어댑터 (snpdb 원본조회, kcgdb 결과저장)
- chat/ AI 채팅 (Ollama, 후순위)
- data/ 정적 데이터 (기선, 특정어업수역 GeoJSON)
config.py를 kcgaidb로 재구성 (DB명, 사용자, 비밀번호)
DB 연결 검증 완료 (kcgaidb 37개 테이블 접근 확인)
Makefile에 dev-prediction / dev-all 타겟 추가
CLAUDE.md에 prediction 섹션 추가
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 12:56:51 +09:00