formula_id: WBS_10_DOTNET_NORMALIZATION_CONTRACT_V1 owner: QuantEngine status: draft goal: "쓰기 경로 정규화와 읽기 경로 역정규화 경계를 고정한다." canonical_write_path: schema: engine_history tables: - source_observation - factor_definition - factor_observation - decision_event - decision_factor_evidence - outcome_evaluation invariant: - "source_observation은 원천 관측 1건당 1행" - "factor_definition은 (factor_id, factor_version) 단일 원장" - "factor_observation은 observation_id를 반드시 참조" - "decision_event는 decision_key로 단일 식별" - "outcome_evaluation은 decision_id + horizon_days 조합으로 단일 식별" canonical_read_path: view: engine_history.training_example_v1 purpose: "모델 학습/캘리브레이션용 역정규화 projection" consumers: - model_training - calibration_jobs - diagnostics forbidden_patterns: - "읽기 모델을 쓰기 원장으로 사용" - "원천 payload를 읽기 projection에 중복 저장" - "직렬 UI 조회를 위해 원장 테이블을 직접 조인해 장기 유지" expected_fields: normalized_tables: source_observation: - observation_id - observed_at - instrument_id - source_name - source_version - payload - provenance factor_observation: - factor_observation_id - observation_id - factor_id - factor_version - observed_at - numeric_value - text_value - gate - provenance decision_event: - decision_id - decision_key - decided_at - instrument_id - action - gate - score - source_version - trace - provenance denormalized_view: - decision_id - decision_key - decided_at - instrument_id - action - decision_gate - score - source_version - horizon_days - realized_return - benchmark_return - excess_return - outcome_class - evaluation_gate - factor_features notes: - "정규화는 쓰기 중복 제거와 provenance 보존이 목적이다." - "역정규화는 학습/진단 편의용 projection으로만 허용한다."