schema_version: v8_9_p0_adoption_plan.v1
meta:
  title: v8_9_p0_adoption_plan
  source_proposal: suggest/quant_investment_engine_v8_9_portfolio_optimizer_canonical_refactored.yaml
  decision_basis: >
    정책 수치는 기존 regime/cluster 연동 수치를 유지하고 v8.9 신규 구조만 추가한다.
    작업 범위는 운영에 즉시 필요한 3개 구멍(portfolio_transition_optimizer,
    sell lot Pareto selector, CE70/CE90/CVaR95 simulation engine)만 우선 차단한다.
    (사용자 확인: 2026-06-17 plan-mode 대화)
  superseded_or_deferred_from_proposal:
    - sector_graph_engine_v8_9 (factor residualization, leader lifecycle, ETF lookthrough)
    - execution_plan_compiler_v8_9 (broker_microstructure_packet capacity 강화)
    - model_governance_v8_9 (kill switch 자동화 전체 세트)
    note: 이 항목들은 별도 후속 제안으로 분리한다. 이 TODO 파일의 범위 밖이다.
  not_adopted_policy_values:
    reason: 기존 spec/risk/portfolio_exposure.yaml의 regime/cluster_state 연동 수치가 v8.9의 고정값보다 더 정교함.
    examples:
      - "cash_floor: v8.9 GROWTH=12.5% 고정 → 기존 regime 7~25% 단계 유지"
      - "semiconductor_cap: v8.9 35% 고정 → 기존 cluster_state 연동 25/35/60% 유지"
  adopted_new_fields_only:
    - single_stock_hard_cap_pct: 20
    - single_stock_soft_cap_pct: 15
    - top3_hard_cap_pct: 65
    - top3_soft_cap_pct: 50

tasks:
  - id: P0-1.1
    title: 신규 cap 필드 추가 (교체 아님, 추가)
    output_file: spec/risk/portfolio_exposure.yaml
    detail: >
      single_stock_hard_cap_pct=20/soft=15, top3_hard_cap_pct=65/soft=50 신규 필드 추가.
      기존 regime cash_floor·cluster_state 반도체 cap은 불변.
    depends_on: []
    acceptance_criteria:
      - 신규 필드가 portfolio_exposure_framework 하위에 추가됨
      - 기존 cash_floor.regime_numbers, cluster_states 수치 변경 없음 (git diff로 확인)

  - id: P0-1.2
    title: formula registry에 PORTFOLIO_TRANSITION_UTILITY_V1 등록
    output_file:
      - spec/formulas/domains/portfolio.yaml
      - spec/13_formula_registry.yaml
    detail: >
      state_vector, candidate_action_schema, hard_veto_order, transition_utility 공식,
      acceptance_margin, NO_TRADE/solver_failure/rank_tie/conflicting_packets fallback을
      명시. spec/13_formula_registry.yaml의 python_harness_supplements.formulas에
      PORTFOLIO_TRANSITION_UTILITY_V1 ID 추가.
    depends_on: [P0-1.1]
    acceptance_criteria:
      - PORTFOLIO_TRANSITION_UTILITY_V1 공식이 spec/formulas/domains/portfolio.yaml에 존재
      - 공식 ID가 spec/13_formula_registry.yaml에 등록됨
      - default_action: NO_TRADE 명시

  - id: P0-1.3
    title: portfolio_transition_optimizer 빌드 도구 작성
    output_file: tools/build_portfolio_transition_optimizer_v1.py
    inputs:
      - Temp/final_decision_packet_active.json
      - Temp/sell_waterfall_engine_v3.json
      - Temp/smart_cash_recovery_v9.json
    detail: >
      기존 tools/build_sell_waterfall_engine_v3.py 패턴(_load, argparse --base/--out)을 따른다.
      candidate_actions를 입력 아티팩트에서 구성하고 hard_constraint_pass 평가 후
      transition_utility_krw, acceptance_margin_krw를 계산해 selected_transition 또는
      NO_TRADE를 결정론적으로 출력한다.
    depends_on: [P0-1.2]
    acceptance_criteria:
      - 입력 아티팩트가 없으면 NO_TRADE_AND_QUARANTINE 반환 (추정값 생성 금지)
      - 출력에 formula_id, gate, reason_codes, source_paths 포함

  - id: P0-1.4
    title: schema + generated model
    output_file:
      - schemas/portfolio_transition_optimizer_v1.schema.json
      - src/quant_engine/models/generated/portfolio_transition_optimizer_v1_schema.py
    depends_on: [P0-1.3]
    acceptance_criteria:
      - schemas/generated와 src/quant_engine/models/generated parity 유지 (AGENTS.md §5)

  - id: P0-1.5
    title: golden case 작성
    output_file: tests/golden/generated/portfolio_transition_optimizer_v1_golden.py
    detail: v8.9 제안서 V89_002(NO_TRADE default), V89_048(solver_failure), V89_049(rank_tie), V89_050(conflicting_packets) 대응 케이스.
    depends_on: [P0-1.4]
    acceptance_criteria:
      - 4개 이상의 실질 assertion이 있는 테스트 (auto-generated stub 패턴 탈피)

  - id: P0-1.6
    title: runtime manifest·decision flow 배선
    output_file:
      - runtime/active_artifact_manifest.yaml
      - spec/09_decision_flow.yaml
    depends_on: [P0-1.5]
    acceptance_criteria:
      - manifest_rows 또는 source_precedence에 portfolio_transition_optimizer_v1 등록

  - id: P0-2.1
    title: SELL_LOT_PARETO_SELECTOR_V1 공식 정의
    output_file: spec/formulas/domains/cash.yaml
    detail: >
      기존 SELL_WATERFALL_ENGINE_V1 옆에 신규 섹션 추가.
      tax_loss_benefit, missed_upside_penalty, reentry_cost 항을 LOT_SELL_SCORE에 추가하고
      동순위 후보 간 Pareto 비교(avoided_tail_loss vs missed_upside 등 다목적) 규칙 명시.
    depends_on: []
    acceptance_criteria:
      - LOT_SELL_SCORE 공식에 3개 신규 항 모두 포함
      - Pareto 비교 규칙(어떤 후보가 다른 후보를 dominate하는지)이 결정론적으로 기술됨

  - id: P0-2.2
    title: build_sell_waterfall_engine_v4.py
    output_file: tools/build_sell_waterfall_engine_v4.py
    detail: tools/build_sell_waterfall_engine_v3.py를 확장. v3 출력을 입력으로 받아 Pareto 선택 단계를 추가.
    depends_on: [P0-2.1]
    acceptance_criteria:
      - v3 출력과 하위호환 (기존 rows 구조 보존, 신규 필드만 추가)

  - id: P0-2.3
    title: sell waterfall v4 golden case
    output_file: tests/golden/generated/sell_waterfall_engine_v4_golden.py
    detail: V89_029(deconcentration_trim), V89_030(profit_lock), V89_031(tax_drag_too_high) 대응.
    depends_on: [P0-2.2]
    acceptance_criteria:
      - 3개 케이스 모두 실질 assertion 포함

  - id: P0-3.1
    title: CE70/CE90/CVaR95 공식 계약 정의
    output_file: spec/formulas/domains/simulation.yaml
    detail: >
      spec/29_backtest_harness_contract.yaml의 insufficient_data 상태를 입력으로 받아
      sample_count_total/same_regime이 v8.9 minimum_sample_rules(SHADOW 30/10, PILOT 80/20,
      LIVE_LIMITED 150/30, LIVE_FULL 300/50) 미달이면 WATCH_ONLY 또는 DATA_MISSING 반환.
      표본이 충분할 때만 walk_forward_bootstrap 실행 경로를 명시. 가짜 분포 생성 금지.
    depends_on: []
    acceptance_criteria:
      - minimum_sample_rules 표본 기준이 AGENTS.md §6b(T+20 30건)와 일치
      - 표본 부족 시 반환값이 DATA_MISSING 또는 WATCH_ONLY로만 표시됨 (추정 금지)

  - id: P0-3.2
    title: build_forecast_simulation_engine_v1.py
    output_file: tools/build_forecast_simulation_engine_v1.py
    inputs:
      - Temp/prediction_accuracy_harness_v2.json
      - spec/29_backtest_harness_contract.yaml
    depends_on: [P0-3.1]
    acceptance_criteria:
      - 현재 T+20 표본 0건 상태에서 실행 시 CE70/CE90/CVaR95가 DATA_MISSING으로 출력됨

  - id: P0-3.3
    title: forecast simulation golden case
    output_file: tests/golden/generated/forecast_simulation_engine_v1_golden.py
    detail: V89_013(missing_CVaR → QUARANTINE), V89_014(same_regime_sample_low → WATCH_ONLY) 대응.
    depends_on: [P0-3.2]
    acceptance_criteria:
      - 2개 케이스 모두 실질 assertion 포함

  - id: P0-4.1
    title: 전체 검증 스위트 실행
    command: |
      python tools/validate_specs.py
      python tools/validate_golden_coverage_100.py
      python tools/validate_calibration_registry_v1.py
      python tools/validate_schema_model_generation_v1.py
      python tools/validate_agents_shrink_v1.py
    depends_on: [P0-1.6, P0-2.3, P0-3.3]
    acceptance_criteria:
      - 5개 validator 모두 PASS
