meta:
  has_code_implementation: true
  code_path:
  - spec\formula_golden_cases_v2.yaml
golden_cases_v2:
- formula_id: TICK_NORMALIZER_V1
  gas_function: tickNormalize_
  gas_file: gas_lib.gs
  python_function: compute_formula_outputs.normalize_tick
  cases:
  - id: tick_exact_multiple
    description: 정확한 배수 — 양측 동일 기대
    inputs:
      price: 185300
    expected:
      normalized: 185300
    tolerance: {}
    provenance: HAND_COMPUTED
    spec_correct_src: spec/13_formula_registry.yaml:TICK_NORMALIZER_V1 tick_table
    note: 185300 < 200000 → tick=100, 185300÷100=1853.0 exact → floor=round=1853 ×
      100 = 185300
  - id: tick_floor_vs_round_diverge_1
    description: 비정확 배수 — GAS(floor)=14520, Python(round)=14530. spec_correct=14520(GAS)
    inputs:
      price: 14527
    expected:
      normalized: 14520
    spec_correct: 14520
    gas_expected: 14520
    python_expected: 14530
    tolerance: {}
    provenance: HAND_COMPUTED
    spec_correct_src: spec/13_formula_registry.yaml:TICK_NORMALIZER_V1
    note: '14527 < 20000 → tick=10.

      SPEC(floor): floor(14527/10)*10 = 1452*10 = 14520 (GAS 동작).

      Python(round): round(14527/10)*10 = round(1452.7)*10 = 1453*10 = 14530.

      [DIVERGENCE] Python은 1 tick 고가 출력 — HTS 입력 시 의도보다 높은 가격.

      B06: Python normalize_tick을 math.floor 방식으로 수정 필요.

      '
  - id: tick_floor_vs_round_diverge_2
    description: 비정확 배수 — GAS=3750, Python=3755. spec_correct=3750(GAS)
    inputs:
      price: 3753
    expected:
      normalized: 3750
    spec_correct: 3750
    gas_expected: 3750
    python_expected: 3755
    tolerance: {}
    provenance: HAND_COMPUTED
    spec_correct_src: spec/13_formula_registry.yaml:TICK_NORMALIZER_V1
    note: '3753 >= 2000, < 5000 → tick=5.

      SPEC(floor): floor(3753/5)*5 = 750*5 = 3750.

      Python(round): round(3753/5)*5 = round(750.6)*5 = 751*5 = 3755.

      [DIVERGENCE] 동일 패턴.

      '
  - id: tick_large_price
    description: 500000원 이상 → tick=1000
    inputs:
      price: 550000
    expected:
      normalized: 550000
    tolerance: {}
    provenance: HAND_COMPUTED
    note: 550000 ÷ 1000 = 550 exact → 양측 동일
- formula_id: VELOCITY_V1
  gas_function: inline_in_calcAntiLateEntryGateV2Impl_
  gas_file: gas_apex_alpha_watch.gs
  python_function: inline_in_compute_formula_outputs
  cases:
  - id: vel_positive
    inputs:
      close: 110000
      prevClose: 100000
      ret5d: 8.0
    expected:
      velocity_1d: 10.0
      velocity_5d: 8.0
    tolerance:
      velocity_1d: 0.001
      velocity_5d: 0.001
    provenance: HAND_COMPUTED
    note: (110000-100000)/100000*100 = 10.0%
  - id: vel_negative
    inputs:
      close: 98000
      prevClose: 100000
      ret5d: -3.5
    expected:
      velocity_1d: -2.0
      velocity_5d: -3.5
    tolerance:
      velocity_1d: 0.001
      velocity_5d: 0.001
    provenance: HAND_COMPUTED
    note: (98000-100000)/100000*100 = -2.0%
  - id: vel_zero
    inputs:
      close: 100000
      prevClose: 100000
      ret5d: 0.0
    expected:
      velocity_1d: 0.0
      velocity_5d: 0.0
    tolerance:
      velocity_1d: 0.001
    provenance: HAND_COMPUTED
- formula_id: PROFIT_LOCK_STAGE_V1
  gas_function: null
  gas_file: gas_data_feed.gs
  python_function: compute_formula_outputs.classify_profit_lock_stage
  cases:
  - id: profit_apex_super
    inputs:
      profit_pct: 65.0
    expected:
      stage: APEX_SUPER
    tolerance: {}
    provenance: SPEC_DERIVED
    note: profit_pct=65 ≥ 60 → APEX_SUPER
  - id: profit_apex_trailing
    inputs:
      profit_pct: 45.0
    expected:
      stage: APEX_TRAILING
    tolerance: {}
    provenance: SPEC_DERIVED
    note: 40 ≤ 45 < 60 → APEX_TRAILING
  - id: profit_lock_30
    inputs:
      profit_pct: 33.0
    expected:
      stage: PROFIT_LOCK_30
    tolerance: {}
    provenance: SPEC_DERIVED
  - id: profit_lock_20
    inputs:
      profit_pct: 22.0
    expected:
      stage: PROFIT_LOCK_20
    tolerance: {}
    provenance: SPEC_DERIVED
  - id: profit_lock_10
    inputs:
      profit_pct: 12.0
    expected:
      stage: PROFIT_LOCK_10
    tolerance: {}
    provenance: SPEC_DERIVED
  - id: profit_breakeven
    inputs:
      profit_pct: 3.0
    expected:
      stage: BREAKEVEN_RATCHET
    tolerance: {}
    provenance: SPEC_DERIVED
    note: 0 ≤ 3 < 10 → BREAKEVEN_RATCHET
  - id: profit_normal
    inputs:
      profit_pct: -5.0
    expected:
      stage: NORMAL
    tolerance: {}
    provenance: SPEC_DERIVED
    note: -5 < 0 → NORMAL
  - id: profit_gas_fix_note
    description: "[B06 수정 완료 2026-05-30] GAS calcPrices_ 단계명이 spec 기준으로 정정됨:\n이전:\
      \ PROFIT_LOCK_STAGE_50/30/20/10/NORMAL (임계값 50%/30%/20%/10%)\n이후: APEX_SUPER(60%)/APEX_TRAILING(40%)/PROFIT_LOCK_30(30%)/PROFIT_LOCK_20(20%)/\n\
      \      PROFIT_LOCK_10(10%)/BREAKEVEN_RATCHET(0%)/NORMAL(<0%)\nGAS golden case는\
      \ 아래 ANTI_LATE_ENTRY_GATE_V2 패턴으로 검증 (calcPrices_ 전체 실행 불가).\n"
- formula_id: ANTI_CHASING_VELOCITY_V1
  gas_function: inline_gate1_of_calcAntiLateEntryGateV2Impl_
  gas_file: gas_apex_alpha_watch.gs
  python_function: compute_formula_outputs.compute_anti_chasing
  cases:
  - id: chase_block
    inputs:
      velocity_1d: 3.5
    expected:
      anti_chasing_verdict: BLOCK_CHASE
      anti_chasing_velocity_status: BLOCKED
    tolerance: {}
    provenance: SPEC_DERIVED
    note: 3.5 ≥ 3.0 → BLOCK_CHASE
  - id: chase_block_boundary
    inputs:
      velocity_1d: 3.0
    expected:
      anti_chasing_verdict: BLOCK_CHASE
      anti_chasing_velocity_status: BLOCKED
    tolerance: {}
    provenance: SPEC_DERIVED
    note: 경계값 3.0 → BLOCK (>= 3.0 포함)
  - id: chase_pullback
    inputs:
      velocity_1d: 2.0
    expected:
      anti_chasing_verdict: PULLBACK_WAIT
      anti_chasing_velocity_status: WAIT
    tolerance: {}
    provenance: SPEC_DERIVED
    note: 1.5 ≤ 2.0 < 3.0 → PULLBACK_WAIT
  - id: chase_clear
    inputs:
      velocity_1d: 0.8
    expected:
      anti_chasing_verdict: CLEAR
      anti_chasing_velocity_status: PASS
    tolerance: {}
    provenance: SPEC_DERIVED
- formula_id: PULLBACK_ENTRY_TRIGGER_V1
  gas_function: null
  gas_file: gas_data_feed.gs
  python_function: compute_formula_outputs.compute_pullback_trigger
  cases:
  - id: pullback_above_zone
    inputs:
      close: 55000
      ma20: 50000
      atr20: 2000
    expected:
      pullback_entry_verdict: ABOVE_PULLBACK_ZONE
      pullback_state: BLOCKED
      pullback_entry_trigger_price: 49000
      pullback_upper_band: 51500
    tolerance: {}
    provenance: HAND_COMPUTED
    note: 'trigger = floor(50000 - 0.5*2000) = floor(49000) = 49000 (tick=50, 49000÷50=980
      exact)

      upper_band = 50000*1.03 = 51500 (51500÷50=1030 exact)

      close=55000 > 51500 → ABOVE_PULLBACK_ZONE

      '
  - id: pullback_in_zone
    inputs:
      close: 51000
      ma20: 50000
      atr20: 2000
    expected:
      pullback_entry_verdict: PULLBACK_ZONE
      pullback_state: PASS
      pullback_entry_trigger_price: 49000
      pullback_upper_band: 51500
    tolerance: {}
    provenance: HAND_COMPUTED
    note: close=51000 ≤ 51500 → PULLBACK_ZONE
- formula_id: SELL_PRICE_SANITY_V1
  gas_function: calcSellPriceSanityV2_
  gas_file: gas_data_feed.gs
  python_function: compute_formula_outputs.check_sell_price_sanity
  cases:
  - id: sanity_price_inversion
    inputs:
      sell_limit_price: 290000
      stop_loss_price: 291000
      prev_close: 300000
    expected:
      sell_price_sanity_status: INVALID_PRICE_INVERSION
      hts_allowed: false
      shadow_ledger: true
    tolerance: {}
    provenance: HAND_COMPUTED
    note: 290000 < 291000 → 가격 역전
  - id: sanity_unrealistic_price
    inputs:
      sell_limit_price: 261000
      stop_loss_price: 250000
      prev_close: 200000
    expected:
      sell_price_sanity_status: INVALID_UNREALISTIC_PRICE
      hts_allowed: false
    tolerance: {}
    provenance: HAND_COMPUTED
    note: 200000*1.30=260000, 261000>260000 → 비현실 상한 초과
  - id: sanity_invalid_tick
    inputs:
      sell_limit_price: 185350
      stop_loss_price: 180000
      prev_close: 200000
    expected:
      sell_price_sanity_status: INVALID_TICK
      hts_allowed: false
    tolerance: {}
    provenance: HAND_COMPUTED
    note: 185350 < 200000 → tick=100, 185350÷100=1853.5 → 나머지 50 → INVALID_TICK
  - id: sanity_pass
    inputs:
      sell_limit_price: 186000
      stop_loss_price: 180000
      prev_close: 200000
    expected:
      sell_price_sanity_status: PASS
      hts_allowed: true
      shadow_ledger: false
    tolerance: {}
    provenance: HAND_COMPUTED
    note: 186000 > 180000, 186000 < 260000, 186000÷100=1860 exact → PASS
- formula_id: ANTI_LATE_ENTRY_GATE_V2
  gas_function: calcAntiLateEntryGateV2Impl_
  gas_file: gas_apex_alpha_watch.gs
  python_function: null
  cases:
  - id: aleg_gate1_block
    description: GATE1 BLOCK — velocity_1d > 3%
    inputs:
      holdings:
      - ticker: TEST
        name: TEST
        close: 103100
      dfMap:
        TEST:
          prevClose: 100000
          ma20: 100000
          rsi14: 50
          flowCredit: 0.4
          volume: 1000000
          avgVolume5d: 1000000
          frg5d: 0
          inst5d: 0
          ret5d: 2.0
          acGate: ''
    expected:
      gate1_status: BLOCK_CHASE
      gate2_status: PASS
      gate3_status: PASS
      final_gate_status: BLOCK
      entry_grade: F
      velocity_1d: 3.1
      dist_weighted_sum: 0.0
    tolerance:
      velocity_1d: 0.01
    provenance: HAND_COMPUTED
    note: (103100-100000)/100000*100 = 3.1% ≥ 3.0 → gate1=BLOCK_CHASE → finalGate=BLOCK
  - id: aleg_gate2_block
    description: GATE2 BLOCK — velocity_5d >= 8%
    inputs:
      holdings:
      - ticker: TEST
        name: TEST
        close: 100500
      dfMap:
        TEST:
          prevClose: 100000
          ma20: 100000
          rsi14: 50
          flowCredit: 0.4
          volume: 1000000
          avgVolume5d: 1000000
          frg5d: 0
          inst5d: 0
          ret5d: 9.0
          acGate: ''
    expected:
      gate1_status: PASS
      gate2_status: BLOCK_CHASE_5D
      gate3_status: PASS
      final_gate_status: BLOCK
      entry_grade: F
      velocity_1d: 0.5
      velocity_5d: 9.0
    tolerance:
      velocity_1d: 0.01
    provenance: HAND_COMPUTED
    note: vel1d=0.5<1.5→PASS, vel5d=9.0>=8.0→BLOCK_CHASE_5D → finalGate=BLOCK
  - id: aleg_gate3_block
    description: GATE3 BLOCK — distWS >= 3.0 (frg5d+inst5d 모두 음수)
    inputs:
      holdings:
      - ticker: TEST
        name: TEST
        close: 100500
      dfMap:
        TEST:
          prevClose: 100000
          ma20: 100000
          rsi14: 50
          flowCredit: 0.4
          volume: 1000000
          avgVolume5d: 1000000
          frg5d: -100000
          inst5d: -50000
          ret5d: 1.0
          acGate: ''
    expected:
      gate1_status: PASS
      gate2_status: PASS
      gate3_status: BLOCK_DISTRIBUTION
      final_gate_status: BLOCK
      entry_grade: F
      dist_weighted_sum: 4.0
    tolerance:
      velocity_1d: 0.01
    provenance: HAND_COMPUTED
    note: frg5d<0→+2.0, inst5d<0→+2.0 → distWS=4.0 ≥ 3.0 → gate3=BLOCK_DISTRIBUTION
  - id: aleg_all_pass_grade_a
    description: All PASS + grade A 조건 (vel1d<0.5, MA20근접, flowCredit>=0.55)
    inputs:
      holdings:
      - ticker: TEST
        name: TEST
        close: 50100
      dfMap:
        TEST:
          prevClose: 50000
          ma20: 50000
          rsi14: 50
          flowCredit: 0.6
          volume: 1000000
          avgVolume5d: 1000000
          frg5d: 100000
          inst5d: 50000
          ret5d: 0.5
          acGate: ''
    expected:
      gate1_status: PASS
      gate2_status: PASS
      gate3_status: PASS
      final_gate_status: PASS
      entry_grade: A
      velocity_1d: 0.2
    tolerance:
      velocity_1d: 0.01
    provenance: HAND_COMPUTED
    note: 'vel1d=(50100-50000)/50000*100=0.2 < 0.5, close=50100≥ma20=50000, 50100≤50000*1.02=51000,
      flowCredit=0.60≥0.55

      → grade A

      '
- formula_id: DYNAMIC_HEAT_GATE_V1
  gas_function: calcDynamicHeatThresholds_
  gas_file: gas_data_feed.gs
  python_function: null
  cases:
  - id: heat_event_shock
    inputs:
      regime: EVENT_SHOCK
    expected:
      hardBlock: 5.0
      halve: 3.5
    tolerance: {}
    provenance: SPEC_DERIVED
  - id: heat_risk_off
    inputs:
      regime: RISK_OFF
    expected:
      hardBlock: 7.0
      halve: 5.0
    tolerance: {}
    provenance: SPEC_DERIVED
  - id: heat_neutral
    inputs:
      regime: NEUTRAL
    expected:
      hardBlock: 10.0
      halve: 7.0
    tolerance: {}
    provenance: SPEC_DERIVED
  - id: heat_risk_on
    inputs:
      regime: RISK_ON
    expected:
      hardBlock: 12.0
      halve: 8.5
    tolerance: {}
    provenance: SPEC_DERIVED
  - id: heat_secular_leader
    inputs:
      regime: SECULAR_LEADER_RISK_ON
    expected:
      hardBlock: 13.0
      halve: 9.0
    tolerance: {}
    provenance: SPEC_DERIVED
- formula_id: POSITION_SIZE_REGIME_SCALE_V1
  gas_function: calcRegimeSizeScale_
  gas_file: gas_data_feed.gs
  python_function: null
  cases:
  - id: scale_event_shock
    inputs:
      regime: EVENT_SHOCK
    expected:
      scale: 0.25
    tolerance: {}
    provenance: SPEC_DERIVED
  - id: scale_risk_off
    inputs:
      regime: RISK_OFF
    expected:
      scale: 0.5
    tolerance: {}
    provenance: SPEC_DERIVED
  - id: scale_neutral
    inputs:
      regime: NEUTRAL
    expected:
      scale: 1.0
    tolerance: {}
    provenance: SPEC_DERIVED
  - id: scale_risk_on
    inputs:
      regime: RISK_ON
    expected:
      scale: 1.1
    tolerance: {}
    provenance: SPEC_DERIVED
  - id: scale_secular_leader
    inputs:
      regime: SECULAR_LEADER_RISK_ON
    expected:
      scale: 1.2
    tolerance: {}
    provenance: SPEC_DERIVED
- formula_id: REGIME_CASH_UPLIFT_V1
  gas_function: calcRegimeCashUplift_
  gas_file: gas_data_feed.gs
  python_function: null
  cases:
  - id: uplift_event_shock
    inputs:
      regime: EVENT_SHOCK
      mrsCashMinPct: 7
    expected:
      effective_min_pct: 20
    tolerance: {}
    provenance: HAND_COMPUTED
    note: max(7, 20) = 20
  - id: uplift_risk_off
    inputs:
      regime: RISK_OFF
      mrsCashMinPct: 12
    expected:
      effective_min_pct: 15
    tolerance: {}
    provenance: HAND_COMPUTED
    note: max(12, 15) = 15
  - id: uplift_risk_on_mrs_wins
    inputs:
      regime: RISK_ON
      mrsCashMinPct: 7
    expected:
      effective_min_pct: 7
    tolerance: {}
    provenance: HAND_COMPUTED
    note: RISK_ON regimeMin=5, max(7, 5) = 7 (MRS가 더 높음)
  - id: uplift_neutral
    inputs:
      regime: NEUTRAL
      mrsCashMinPct: 10
    expected:
      effective_min_pct: 10
    tolerance: {}
    provenance: HAND_COMPUTED
    note: NEUTRAL regimeMin=0, max(10, 0) = 10
- formula_id: DRAWDOWN_GUARD_V1
  gas_function: calcDrawdownGuard_
  gas_file: gas_data_feed.gs
  python_function: null
  cases:
  - id: drawdown_normal
    inputs:
      consecutive_losses: 0
    expected:
      state: NORMAL
      buy_scale: 1.0
    tolerance: {}
    provenance: SPEC_DERIVED
  - id: drawdown_caution
    inputs:
      consecutive_losses: 2
    expected:
      state: CAUTION_BUY
      buy_scale: 0.75
    tolerance: {}
    provenance: SPEC_DERIVED
  - id: drawdown_reduce
    inputs:
      consecutive_losses: 3
    expected:
      state: REDUCE_BUY
      buy_scale: 0.5
    tolerance: {}
    provenance: SPEC_DERIVED
  - id: drawdown_no_buy
    inputs:
      consecutive_losses: 5
    expected:
      state: NO_BUY
      buy_scale: 0.0
    tolerance: {}
    provenance: SPEC_DERIVED
  - id: drawdown_no_buy_extreme
    inputs:
      consecutive_losses: 7
    expected:
      state: NO_BUY
      buy_scale: 0.0
    tolerance: {}
    provenance: SPEC_DERIVED
- formula_id: POSITION_COUNT_LIMIT_V1
  gas_function: calcPositionCountLimit_
  gas_file: gas_data_feed.gs
  python_function: null
  cases:
  - id: count_neutral_pass
    inputs:
      holdings_count: 8
      marketRegime: NEUTRAL
    expected:
      gate_status: PASS
      max_count: 8
      excess_count: 0
    tolerance: {}
    provenance: SPEC_DERIVED
    note: count=8 = max=8 → NOT > 8 → PASS
  - id: count_neutral_block
    inputs:
      holdings_count: 9
      marketRegime: NEUTRAL
    expected:
      gate_status: POSITION_COUNT_BLOCK
      max_count: 8
      excess_count: 1
    tolerance: {}
    provenance: SPEC_DERIVED
  - id: count_risk_off_pass
    inputs:
      holdings_count: 6
      marketRegime: RISK_OFF
    expected:
      gate_status: PASS
      max_count: 6
    tolerance: {}
    provenance: SPEC_DERIVED
    note: count=6 = max=6 → NOT > 6 → PASS
  - id: count_event_shock_block
    inputs:
      holdings_count: 7
      marketRegime: EVENT_SHOCK
    expected:
      gate_status: POSITION_COUNT_BLOCK
      max_count: 6
      excess_count: 1
    tolerance: {}
    provenance: SPEC_DERIVED
- formula_id: CASH_FLOOR_V1
  gas_function: calcCashFloor_
  gas_file: gas_data_feed.gs
  python_function: null
  cases:
  - id: cash_floor_pass_low_mrs
    inputs:
      mrsScore: 2
      settlementCashPct: 8
    expected:
      minPct: 7
      status: PASS
    tolerance: {}
    provenance: HAND_COMPUTED
    note: mrsScore=2 ≤ 3 → minPct=7. 8 ≥ 7 → PASS
  - id: cash_floor_trim_mid_mrs
    inputs:
      mrsScore: 5
      settlementCashPct: 8
    expected:
      minPct: 10
      status: TRIM_REQUIRED
    tolerance: {}
    provenance: HAND_COMPUTED
    note: mrsScore=5 ≤ 7 → minPct=10. 8 < 10 but 8 ≥ 10*0.7=7.0 → TRIM_REQUIRED
  - id: cash_floor_hard_block
    inputs:
      mrsScore: 5
      settlementCashPct: 5
    expected:
      minPct: 10
      status: HARD_BLOCK
    tolerance: {}
    provenance: HAND_COMPUTED
    note: mrsScore=5 → minPct=10. 5 < 10*0.7=7.0 → HARD_BLOCK
  - id: cash_floor_trim_high_mrs
    inputs:
      mrsScore: 8
      settlementCashPct: 12
    expected:
      minPct: 15
      status: TRIM_REQUIRED
    tolerance: {}
    provenance: HAND_COMPUTED
    note: mrsScore=8 ≤ 10 → minPct=15. 12 < 15 but 12 ≥ 15*0.7=10.5 → TRIM_REQUIRED
- formula_id: SEMICONDUCTOR_CLUSTER_GATE_V1
  gas_function: calcSemiconductorClusterGate_
  gas_file: gas_data_feed.gs
  python_function: null
  cases:
  - id: cluster_pass_neutral
    inputs:
      holdings:
      - ticker: 005930
        weightPct: 15.0
        name: 삼성전자
      - ticker: '000660'
        weightPct: 8.0
        name: SK하이닉스
      - ticker: '012450'
        weightPct: 5.0
        name: 기타
      marketRegime: NEUTRAL
    expected:
      gate_status: PASS
      combined_pct: 23.0
      cap_pct: 35.0
    tolerance:
      combined_pct: 0.01
    provenance: HAND_COMPUTED
    note: NEUTRAL cap=35%. 23% < 35×0.80=28% warnThreshold → PASS
  - id: cluster_warn_neutral
    inputs:
      holdings:
      - ticker: 005930
        weightPct: 18.0
        name: 삼성전자
      - ticker: '000660'
        weightPct: 10.0
        name: SK하이닉스
      marketRegime: NEUTRAL
    expected:
      gate_status: CLUSTER_OVERWEIGHT_WARN
      combined_pct: 28.0
      cap_pct: 35.0
    tolerance:
      combined_pct: 0.01
    provenance: HAND_COMPUTED
    note: 28% >= 35×0.80=28(warn) but < 35(cap) → CLUSTER_OVERWEIGHT_WARN. 기존 BLOCK→WARN
      완화.
  - id: cluster_warn_risk_off
    inputs:
      holdings:
      - ticker: 005930
        weightPct: 12.0
        name: 삼성전자
      - ticker: '000660'
        weightPct: 9.0
        name: SK하이닉스
      marketRegime: RISK_OFF
    expected:
      gate_status: CLUSTER_OVERWEIGHT_WARN
      combined_pct: 21.0
      cap_pct: 25.0
    tolerance:
      combined_pct: 0.01
    provenance: HAND_COMPUTED
    note: RISK_OFF cap=25%. 21%>=25×0.80=20(warn) but <25(cap) → CLUSTER_OVERWEIGHT_WARN.
  - id: cluster_block_risk_off_over_cap
    inputs:
      holdings:
      - ticker: 005930
        weightPct: 17.0
        name: 삼성전자
      - ticker: '000660'
        weightPct: 9.0
        name: SK하이닉스
      marketRegime: RISK_OFF
    expected:
      gate_status: CLUSTER_BLOCK
      combined_pct: 26.0
      cap_pct: 25.0
    tolerance:
      combined_pct: 0.01
    provenance: HAND_COMPUTED
    note: 'RISK_OFF: 26% >= cap(25%) AND isRiskOff → CLUSTER_BLOCK.'
  - id: cluster_pass_risk_on_high
    description: RISK_ON에서 40% → 신규 허용 (기존이면 BLOCK)
    inputs:
      holdings:
      - ticker: 005930
        weightPct: 30.0
        name: 삼성전자
      - ticker: '000660'
        weightPct: 10.0
        name: SK하이닉스
      marketRegime: RISK_ON
    expected:
      gate_status: CLUSTER_OVERWEIGHT_WARN
      combined_pct: 40.0
      cap_pct: 45.0
    tolerance:
      combined_pct: 0.01
    provenance: HAND_COMPUTED
    note: RISK_ON cap=45%. 40%>=45×0.80=36(warn) but <45(cap) → WARN. 반도체 주도 참여 허용.
- formula_id: PROFIT_RATCHET_TIERED_V2
  gas_function: null
  gas_file: gas_data_feed.gs
  python_function: compute_formula_outputs.compute_trailing_stop_v2
  cases:
  - id: ratchet_apex_super
    inputs:
      profit_pct: 65.0
      highest_close: 200000
      atr20: 5000
      ratchet_stop: 180000
      average_cost: 120000
    expected:
      ratchet_stage_v2: APEX_SUPER
      auto_trailing_stop_v2: 194000
    tolerance: {}
    provenance: HAND_COMPUTED
    note: 'stage=APEX_SUPER(65>=60). raw=200000-1.2*5000=200000-6000=194000.

      194000 > ratchet=180000 → max=194000.

      tick: 194000 < 200000 → tick=100, 194000÷100=1940 exact → 194000.

      '
  - id: ratchet_apex_trailing
    inputs:
      profit_pct: 43.0
      highest_close: 150000
      atr20: 4000
      ratchet_stop: 130000
      average_cost: 105000
    expected:
      ratchet_stage_v2: APEX_TRAILING
      auto_trailing_stop_v2: 144000
    tolerance: {}
    provenance: HAND_COMPUTED
    note: 'stage=APEX_TRAILING(43>=40). raw=150000-1.5*4000=150000-6000=144000.

      144000 > 130000 → max=144000.

      tick: 144000 < 200000 → tick=100, 144000÷100=1440 exact → 144000.

      '
  - id: ratchet_profit_lock_30
    inputs:
      profit_pct: 32.0
      highest_close: 100000
      atr20: 3000
      ratchet_stop: 88000
      average_cost: 76000
    expected:
      ratchet_stage_v2: PROFIT_LOCK_30
      auto_trailing_stop_v2: 94000
    tolerance: {}
    provenance: HAND_COMPUTED
    note: 'stage=PROFIT_LOCK_30(32>=30). raw=100000-2.0*3000=94000.

      94000 > 88000 → max=94000.

      tick: 94000 < 200000 → tick=100, 94000÷100=940 exact → 94000.

      '
  - id: ratchet_normal_no_trailing
    inputs:
      profit_pct: 2.0
      highest_close: 50000
      atr20: 1000
      ratchet_stop: null
      average_cost: 49000
    expected:
      ratchet_stage_v2: BREAKEVEN_RATCHET
      auto_trailing_stop_v2: null
    tolerance: {}
    provenance: SPEC_DERIVED
    note: BREAKEVEN_RATCHET(0<=2<10) → trailing=None
- formula_id: WIN_LOSS_STREAK_GUARD_V1
  gas_function: calcWinLossStreakGuard_
  gas_file: gas_data_feed.gs
  python_function: null
  cases:
  - id: wlsg_edge_ok
    inputs:
      win_rate_30: 0.55
      trades_used: 30
    expected:
      state: EDGE_OK
      buy_scale: 1.0
    tolerance: {}
    provenance: SPEC_DERIVED
    note: win_rate=55% ≥ 45% → EDGE_OK, scale=1.0
  - id: wlsg_edge_weak
    inputs:
      win_rate_30: 0.42
      trades_used: 20
    expected:
      state: EDGE_WEAK
      buy_scale: 0.75
    tolerance: {}
    provenance: SPEC_DERIVED
    note: 0.40 ≤ 42% < 45% → EDGE_WEAK, scale=0.75
  - id: wlsg_edge_degraded
    inputs:
      win_rate_30: 0.35
      trades_used: 15
    expected:
      state: EDGE_DEGRADED
      buy_scale: 0.5
    tolerance: {}
    provenance: SPEC_DERIVED
    note: 0.30 ≤ 35% < 40% → EDGE_DEGRADED, scale=0.50
  - id: wlsg_edge_critical
    inputs:
      win_rate_30: 0.25
      trades_used: 12
    expected:
      state: EDGE_CRITICAL
      buy_scale: 0.25
    tolerance: {}
    provenance: SPEC_DERIVED
    note: 25% < 30% → EDGE_CRITICAL, scale=0.25
  - id: wlsg_insufficient
    inputs:
      win_rate_30: 0.6
      trades_used: 8
    expected:
      state: INSUFFICIENT_HISTORY
      buy_scale: 1.0
    tolerance: {}
    provenance: SPEC_DERIVED
    note: trades_used=8 < 10 → INSUFFICIENT_HISTORY
- formula_id: SINGLE_POSITION_WEIGHT_CAP_V1
  gas_function: calcSinglePositionWeightCap_
  gas_file: gas_data_feed.gs
  python_function: null
  cases:
  - id: spwc_pass_neutral
    inputs:
      holdings:
      - ticker: 005930
        weightPct: 18.0
        name: 삼성전자
      marketRegime: NEUTRAL
    expected:
      gate_status: PASS
    tolerance: {}
    provenance: HAND_COMPUTED
    note: 삼성전자 NEUTRAL cap=28%. 18% < 28% → PASS. 기존 20% cap → 28%로 완화.
  - id: spwc_pass_neutral_leader
    inputs:
      holdings:
      - ticker: 005930
        weightPct: 27.0
        name: 삼성전자
      marketRegime: NEUTRAL
    expected:
      gate_status: PASS
    tolerance: {}
    provenance: HAND_COMPUTED
    note: 삼성전자 27% < 28%(NEUTRAL cap) → PASS. 기존이면 22%>20%로 OVERWEIGHT_TRIM이었음.
  - id: spwc_overweight_neutral
    inputs:
      holdings:
      - ticker: 005930
        weightPct: 29.0
        name: 삼성전자
      marketRegime: NEUTRAL
    expected:
      gate_status: OVERWEIGHT_TRIM
    tolerance: {}
    provenance: HAND_COMPUTED
    note: 삼성전자 29% > 28%(NEUTRAL cap) → OVERWEIGHT_TRIM.
  - id: spwc_overweight_risk_off
    inputs:
      holdings:
      - ticker: 005930
        weightPct: 19.0
        name: 삼성전자
      marketRegime: RISK_OFF
    expected:
      gate_status: OVERWEIGHT_TRIM
    tolerance: {}
    provenance: HAND_COMPUTED
    note: 삼성전자 RISK_OFF cap=18%. 19% > 18% → OVERWEIGHT_TRIM.
  - id: spwc_pass_risk_off
    inputs:
      holdings:
      - ticker: 005930
        weightPct: 17.0
        name: 삼성전자
      marketRegime: RISK_OFF
    expected:
      gate_status: PASS
    tolerance: {}
    provenance: HAND_COMPUTED
    note: 삼성전자 RISK_OFF cap=18%. 17% < 18% → PASS.
  - id: spwc_pass_risk_on_leader
    description: RISK_ON에서 40% 한도 — 기존 20% 대비 2배 허용
    inputs:
      holdings:
      - ticker: 005930
        weightPct: 39.0
        name: 삼성전자
      marketRegime: RISK_ON
    expected:
      gate_status: PASS
    tolerance: {}
    provenance: HAND_COMPUTED
    note: 삼성전자 RISK_ON cap=40%. 39% < 40% → PASS. 반도체 주도 상승장 참여 허용.
- formula_id: REGIME_TRIM_GUIDANCE_V1
  gas_function: calcRegimeTrimGuidance_
  gas_file: gas_data_feed.gs
  python_function: null
  cases:
  - id: trim_risk_on
    inputs:
      regime: RISK_ON
    expected:
      phase: ADVANCE
      satellite_trim_pct_min: 0
      satellite_trim_pct_max: 5
    tolerance: {}
    provenance: SPEC_DERIVED
    note: RISK_ON → ADVANCE 단계, 위성 감축 최소화
  - id: trim_neutral
    inputs:
      regime: NEUTRAL
    expected:
      phase: PULLBACK_IN_UPTREND
      satellite_trim_pct_min: 5
      satellite_trim_pct_max: 10
    tolerance: {}
    provenance: SPEC_DERIVED
  - id: trim_risk_off
    inputs:
      regime: RISK_OFF
    expected:
      phase: BREAKDOWN
      satellite_trim_pct_min: 25
      satellite_trim_pct_max: 50
    tolerance: {}
    provenance: SPEC_DERIVED
  - id: trim_event_shock
    inputs:
      regime: EVENT_SHOCK
    expected:
      phase: BREAKDOWN
      satellite_trim_pct_min: 25
      satellite_trim_pct_max: 50
    tolerance: {}
    provenance: SPEC_DERIVED
    note: EVENT_SHOCK = RISK_OFF와 동일 BREAKDOWN 단계
  - id: trim_secular_leader
    inputs:
      regime: SECULAR_LEADER_RISK_ON
    expected:
      phase: ADVANCE
      satellite_trim_pct_min: 0
      satellite_trim_pct_max: 5
    tolerance: {}
    provenance: SPEC_DERIVED
- formula_id: HEAT_CONCENTRATION_ALERT_V1
  gas_function: calcHeatConcentrationAlert_
  gas_file: gas_data_feed.gs
  python_function: null
  cases:
  - id: heat_concentrated
    inputs:
      holdings:
      - ticker: 005930
        name: 삼성전자
        avgCost: 280000
        stopPrice: 250000
        holdingQty: 100
      - ticker: '000660'
        name: SK하이닉스
        avgCost: 200000
        stopPrice: 180000
        holdingQty: 50
      totalHeatKrw: 4000000
    expected:
      gate: HEAT_CONCENTRATED
    tolerance: {}
    provenance: HAND_COMPUTED
    note: '005930 heatI=(280000-250000)*100=3,000,000. 3M/4M=75% ≥ 50% → HEAT_CONCENTRATED.

      000660 heatI=(200000-180000)*50=1,000,000. 1M/4M=25% → PASS.

      gate=HEAT_CONCENTRATED.

      '
  - id: heat_concentrated_by_second_holding
    inputs:
      holdings:
      - ticker: 005930
        name: 삼성전자
        avgCost: 280000
        stopPrice: 270000
        holdingQty: 100
      - ticker: '000660'
        name: SK하이닉스
        avgCost: 200000
        stopPrice: 185000
        holdingQty: 100
      totalHeatKrw: 2500000
    expected:
      gate: HEAT_CONCENTRATED
    tolerance: {}
    provenance: HAND_COMPUTED
    note: '005930 heatI=(280000-270000)*100=1,000,000. 1M/2.5M=40% < 50% → PASS.

      000660 heatI=(200000-185000)*100=1,500,000. 1.5M/2.5M=60% ≥ 50% → HEAT_CONCENTRATED.

      gate=HEAT_CONCENTRATED (000660 초과).

      '
  - id: heat_pass_equal
    inputs:
      holdings:
      - ticker: A
        name: A
        avgCost: 100000
        stopPrice: 90000
        holdingQty: 100
      - ticker: B
        name: B
        avgCost: 100000
        stopPrice: 90000
        holdingQty: 100
      - ticker: C
        name: C
        avgCost: 100000
        stopPrice: 90000
        holdingQty: 100
      totalHeatKrw: 3000000
    expected:
      gate: PASS
    tolerance: {}
    provenance: HAND_COMPUTED
    note: '각 heatI=(100000-90000)*100=1,000,000. 각 share=1M/3M=33.3% < 50% → 모두 PASS.

      '
- formula_id: SECTOR_CONCENTRATION_LIMIT_V1
  gas_function: calcSectorConcentrationGate_
  gas_file: gas_data_feed.gs
  python_function: null
  cases:
  - id: sector_pass_neutral
    inputs:
      holdings:
      - ticker: 005930
        weightPct: 20.0
        name: 삼성전자
      - ticker: '000270'
        weightPct: 15.0
        name: 기아
      - ticker: '012450'
        weightPct: 10.0
        name: 한화에어로스페이스
      marketRegime: NEUTRAL
    expected:
      gate_status: PASS
    tolerance: {}
    provenance: HAND_COMPUTED
    note: 'TICKER_SECTOR_MAP: 005930→반도체(20%), 000270→자동차(15%), 012450→방산(10%).

      최대섹터=반도체(20%) < 40% cap → PASS.

      '
  - id: sector_block_neutral
    inputs:
      holdings:
      - ticker: 005930
        weightPct: 30.0
        name: 삼성전자
      - ticker: '000660'
        weightPct: 15.0
        name: SK하이닉스
      marketRegime: NEUTRAL
    expected:
      gate_status: BLOCK_SECTOR
    tolerance: {}
    provenance: HAND_COMPUTED
    note: '005930→반도체(30%), 000660→반도체(15%). 반도체 합산=45% ≥ 40% cap → BLOCK_SECTOR.

      '
  - id: sector_block_risk_off_strict
    inputs:
      holdings:
      - ticker: 005930
        weightPct: 20.0
        name: 삼성전자
      - ticker: '000660'
        weightPct: 18.0
        name: SK하이닉스
      marketRegime: RISK_OFF
    expected:
      gate_status: BLOCK_SECTOR
    tolerance: {}
    provenance: HAND_COMPUTED
    note: RISK_OFF cap=35%. 반도체 합산=38% ≥ 35% → BLOCK_SECTOR.
- formula_id: CASH_SHORTFALL_V1
  gas_function: calcCashShortfallHarness_
  gas_file: gas_data_feed.gs
  python_function: null
  cases:
  - id: shortfall_exists
    inputs:
      asResult:
        settlementCashD2Krw: 3000000
      totalAsset: 300000000
      cashFloorInfo:
        minPct: 7
      mrsScore: 5
    expected:
      cash_target_pct: 12.5
      shortfall_min_krw_gt_0: true
    tolerance:
      cash_target_pct: 0.01
    provenance: HAND_COMPUTED
    note: 'target_pct = max(5 + (5/10)*15, 7) = max(5+7.5, 7) = max(12.5, 7) = 12.5%.

      target_krw = 300M * 12.5% = 37,500,000.

      shortfall = max(0, 37,500,000 - 3,000,000) = 34,500,000 > 0.

      '
  - id: shortfall_none
    inputs:
      asResult:
        settlementCashD2Krw: 50000000
      totalAsset: 300000000
      cashFloorInfo:
        minPct: 7
      mrsScore: 2
    expected:
      cash_target_pct: 8.0
      shortfall_min_krw_gt_0: false
    tolerance:
      cash_target_pct: 0.01
    provenance: HAND_COMPUTED
    note: 'target_pct = max(5 + (2/10)*15, 7) = max(5+3, 7) = max(8, 7) = 8%.

      target_krw = 300M * 8% = 24,000,000.

      현금=50,000,000 > target → shortfall=0.

      '
- formula_id: PORTFOLIO_DRAWDOWN_GATE_V1
  gas_function: null
  gas_file: gas_data_feed.gs
  python_function: null
  note: 'calcPortfolioDrawdownGate_는 SpreadsheetApp(settings 시트 접근) 의존.

    GAS vm 테스트 불가 — 로직 스펙만 명세.

    drawdown > 20% → DRAWDOWN_FORCE_RISK_OFF.

    drawdown > 10% → DRAWDOWN_CAUTION.

    else → PASS.

    '
  cases:
  - id: drawdown_force_risk_off
    description: 낙폭 > 20% → 신규 BUY 금지
    inputs:
      peak_krw: 500000000
      current_krw: 395000000
    expected:
      drawdown_pct: 21.0
      gate: DRAWDOWN_FORCE_RISK_OFF
    tolerance:
      drawdown_pct: 0.01
    provenance: HAND_COMPUTED
    note: (500M-395M)/500M*100=21% > 20% → DRAWDOWN_FORCE_RISK_OFF
  - id: drawdown_caution
    inputs:
      peak_krw: 500000000
      current_krw: 440000000
    expected:
      drawdown_pct: 12.0
      gate: DRAWDOWN_CAUTION
    tolerance:
      drawdown_pct: 0.01
    provenance: HAND_COMPUTED
    note: (500M-440M)/500M*100=12% → DRAWDOWN_CAUTION
  - id: drawdown_pass
    inputs:
      peak_krw: 500000000
      current_krw: 480000000
    expected:
      drawdown_pct: 4.0
      gate: PASS
    tolerance:
      drawdown_pct: 0.01
    provenance: HAND_COMPUTED
    note: (500M-480M)/500M*100=4% < 10% → PASS
- formula_id: K2_STAGED_REBOUND_SELL_V1
  gas_function: null
  gas_file: gas_data_feed.gs
  python_function: null
  note: K2 분할 공식은 calcApexTradePlan_ 인라인. 핵심 수식을 인라인 검증.
  cases:
  - id: k2_split_even
    description: 짝수 수량 → 50/50 분할
    inputs:
      base_qty: 100
      prevClose: 50000
      atr20: 2000
    expected:
      immediate_qty: 50
      rebound_wait_qty: 50
      rebound_trigger_price: 51000
    tolerance: {}
    provenance: HAND_COMPUTED
    note: 'immediate=floor(100/2)=50, rebound=100-50=50.

      trigger=floor(50000+0.5*2000)=floor(51000)=51000. tick=50(20000≤51000<50000?
      아니, 51000<200000→tick=100). floor(51000/100)*100=510*100=51000.

      '
  - id: k2_split_odd
    description: 홀수 수량 → floor 분할
    inputs:
      base_qty: 101
      prevClose: 50000
      atr20: 2000
    expected:
      immediate_qty: 50
      rebound_wait_qty: 51
      rebound_trigger_price: 51000
    tolerance: {}
    provenance: HAND_COMPUTED
    note: immediate=floor(101/2)=50, rebound=101-50=51.
- formula_id: STOP_BREACH_ALERT_V1
  gas_function: calcStopBreachAlert_
  gas_file: gas_data_feed.gs
  python_function: null
  cases:
  - id: stop_breach
    inputs:
      holdings:
      - ticker: 005930
        name: 삼성전자
        close: 280000
        stopPrice: 285000
        stopPriceSrc: MANUAL
      dfMap:
        005930:
          close: 280000
          prevClose: 290000
    expected:
      gate: BREACH
    tolerance: {}
    provenance: HAND_COMPUTED
    note: close=280000 <= stop=285000 → BREACH_IMMEDIATE_EXIT, gate=BREACH
  - id: stop_approaching
    inputs:
      holdings:
      - ticker: 005930
        name: 삼성전자
        close: 290000
        stopPrice: 285000
        stopPriceSrc: MANUAL
      dfMap:
        005930:
          close: 290000
          prevClose: 295000
    expected:
      gate: APPROACHING
    tolerance: {}
    provenance: HAND_COMPUTED
    note: 290000 > 285000 but 290000 <= 285000*1.03=293550 → STOP_APPROACHING, gate=APPROACHING
  - id: stop_pass
    inputs:
      holdings:
      - ticker: 005930
        name: 삼성전자
        close: 300000
        stopPrice: 285000
        stopPriceSrc: MANUAL
      dfMap:
        005930:
          close: 300000
          prevClose: 295000
    expected:
      gate: PASS
    tolerance: {}
    provenance: HAND_COMPUTED
    note: 300000 > 285000*1.03=293550 → PASS
- formula_id: PORTFOLIO_HEALTH_SCORE_V1
  gas_function: calcPortfolioHealthScore_
  gas_file: gas_data_feed.gs
  python_function: null
  cases:
  - id: health_critical
    inputs:
      gateMap:
        cash_floor_status: HARD_BLOCK
        heat_gate: PASS
        position_count: PASS
    expected:
      label: CRITICAL
      score: 70
    tolerance: {}
    provenance: HAND_COMPUTED
    note: 'HARD_BLOCK=CRITICAL(1건): label=CRITICAL, score=100-1*30=70'
  - id: health_caution_three_warn
    inputs:
      gateMap:
        heat_gate: TRIM_REQUIRED
        drawdown: DRAWDOWN_CAUTION
        beta: WARN_BETA
    expected:
      label: CRITICAL
      score: 70
    tolerance: {}
    provenance: HAND_COMPUTED
    note: 'CAUTION 3건(warnCount=3): label=CRITICAL(warnCount>=3), score=100-0*30-3*10=70'
  - id: health_caution_one_warn
    inputs:
      gateMap:
        heat_gate: TRIM_REQUIRED
        other: PASS
    expected:
      label: CAUTION
      score: 90
    tolerance: {}
    provenance: HAND_COMPUTED
    note: 'CAUTION 1건(warnCount=1): label=CAUTION, score=100-0-10=90'
  - id: health_healthy
    inputs:
      gateMap:
        cash_floor_status: PASS
        heat_gate: PASS
        position_count: PASS
    expected:
      label: HEALTHY
      score: 100
    tolerance: {}
    provenance: HAND_COMPUTED
    note: 모두 PASS → label=HEALTHY, score=100
- formula_id: SECTOR_ROTATION_MOMENTUM_V1
  gas_function: calcSectorRotationMomentum_
  gas_file: gas_data_feed.gs
  python_function: null
  cases:
  - id: sector_fading
    inputs:
      sectorFlowData:
        반도체:
          rank: 5
          prevRank: 2
          prevRankW2: 3
    expected_first_row:
      sector: 반도체
      momentum_state: FADING
    tolerance: {}
    provenance: HAND_COMPUTED
    note: rankDeltaW1=5-2=3>=2, rankDeltaW2=5-3=2>=2 → FADING
  - id: sector_topping_out
    inputs:
      sectorFlowData:
        AI전력:
          rank: 2
          prevRank: 1
          prevRankW2: 1
    expected_first_row:
      momentum_state: TOPPING_OUT
    tolerance: {}
    provenance: HAND_COMPUTED
    note: rank=2<=3 AND rankDeltaW1=2-1=1>=1 → TOPPING_OUT
  - id: sector_rising
    inputs:
      sectorFlowData:
        방산:
          rank: 3
          prevRank: 6
          prevRankW2: 7
    expected_first_row:
      momentum_state: RISING
    tolerance: {}
    provenance: HAND_COMPUTED
    note: rankDeltaW1=3-6=-3<=-2 → RISING
  - id: sector_stable
    inputs:
      sectorFlowData:
        자동차:
          rank: 4
          prevRank: 4
          prevRankW2: 5
    expected_first_row:
      momentum_state: STABLE
    tolerance: {}
    provenance: HAND_COMPUTED
    note: rankDeltaW1=0, rankDeltaW2=-1, 어떤 조건도 미충족 → STABLE
- formula_id: BREAKOUT_QUALITY_GATE_V2
  gas_function: calcBreakoutQualityGate_
  gas_file: gas_data_feed.gs
  python_function: null
  cases:
  - id: breakout_pilot_allowed
    inputs:
      h:
        ticker: 005930
        name: 삼성전자
        close: 50000
      df:
        close: 50000
        prevClose: 48000
        ma20: 48000
        rsi14: 55
        volume: 1500000
        avgVolume5d: 1000000
        ret5d: 4.0
      alphaRow:
        timing_score_exit: 0
        late_chase_risk_score: 0
      distRow:
        distribution_risk_score: 0
    expected:
      breakout_quality_gate: PILOT_ALLOWED
    tolerance: {}
    provenance: HAND_COMPUTED
    note: 'ret3d=4*0.6=2.4<7(-0), disparity=(50000/48000-1)*100=4.17<10(-0),

      rsi14=55(45~65→+10), vol=1.5M>=1M*1.5=1.5M AND ret1d=(50000-48000)/48000*100=4.17>=2
      AND ret3d=2.4<5(→+25)

      score=50+10+25=85→PILOT_ALLOWED

      '
  - id: breakout_blocked_late_chase
    inputs:
      h:
        ticker: 005930
        name: 삼성전자
        close: 55000
      df:
        close: 55000
        prevClose: 48000
        ma20: 48000
        rsi14: 78
        volume: 500000
        avgVolume5d: 1000000
        ret5d: 14.0
      alphaRow:
        timing_score_exit: 55
        late_chase_risk_score: 0
      distRow:
        distribution_risk_score: 0
    expected:
      breakout_quality_gate: BLOCKED_LATE_CHASE
    tolerance: {}
    provenance: HAND_COMPUTED
    note: 'ret3d=14*0.6=8.4>=7(-30), disparity=(55000/48000-1)*100=14.6>10(-25),

      rsi14=78>75(-20), timing_score_exit=55>=50(-50).

      score=50-30-25-20-50=-75→max(0,-75)=0<10→BLOCKED_LATE_CHASE

      '
- formula_id: ANTI_WHIPSAW_GATE_V1
  gas_function: calcAntiWhipsawGate_
  gas_file: gas_data_feed.gs
  python_function: null
  cases:
  - id: whipsaw_confirmed_sell
    inputs:
      h:
        ticker: 005930
        name: 삼성전자
        close: 50000
      df:
        inst5d: -100000
        frg5d: -50000
        valSurgePct: 0
        consecutiveSellSignals5d: 0
        ret5d: -2
        ma20: 50000
      kospiRet5d: 1
    expected:
      anti_whipsaw_gate: CONFIRMED_SELL
    tolerance: {}
    provenance: HAND_COMPUTED
    note: inst<0, frg<0 → score=0<10 → CONFIRMED_SELL
  - id: whipsaw_auto_released
    inputs:
      h:
        ticker: 005930
        name: 삼성전자
        close: 52000
      df:
        inst5d: 100000
        frg5d: 50000
        valSurgePct: 10
        consecutiveSellSignals5d: 5
        ret5d: 3
        ma20: 50000
      kospiRet5d: 1
    expected:
      anti_whipsaw_gate: WHIPSAW_AUTO_RELEASED
      anti_whipsaw_hold_days: 0
    tolerance: {}
    provenance: HAND_COMPUTED
    note: 'consec_sell>=5(+20), inst>0(+30), frg>0(+20), sectorRS5d=1.03>1(+15)

      score=20+30+20+15=85>=30. clearCnt: inst>0✓, frg>0✓, close>ma20(52000>50000)✓
      → 3개 → AUTO_RELEASED

      '
- formula_id: BREAKEVEN_RATCHET_V1
  gas_function: calcProfitPreservationRow_
  gas_file: gas_data_feed.gs
  python_function: null
  note: calcProfitPreservationRow_ 내 profit_preservation_state 판정 로직
  cases:
  - id: breakeven_ratchet_by_pct
    description: 수익률 8% 이상 → BREAKEVEN_RATCHET
    inputs:
      h:
        ticker: 005930
        name: 삼성전자
        avgCost: 50000
        stopPrice: 48000
        close: 54500
      df:
        atr20: 2000
        close: 54500
      priceRow: null
      distributionRow: null
    expected:
      profit_preservation_state: BREAKEVEN_RATCHET
    tolerance: {}
    provenance: HAND_COMPUTED
    note: profitPct=(54500-50000)/50000*100=9% >= 8% → BREAKEVEN_RATCHET
  - id: profit_lock_30
    description: 수익률 30% 이상 → PROFIT_LOCK_30
    inputs:
      h:
        ticker: 005930
        name: 삼성전자
        avgCost: 50000
        stopPrice: 48000
        close: 65500
      df:
        atr20: 2000
        close: 65500
      priceRow: null
      distributionRow: null
    expected:
      profit_preservation_state: PROFIT_LOCK_30
    tolerance: {}
    provenance: HAND_COMPUTED
    note: profitPct=(65500-50000)/50000*100=31% >= 30% → PROFIT_LOCK_30
- formula_id: MARKET_WEIGHT_AWARE_CLUSTER_GATE_V1
  gas_function: calcSemiconductorClusterGate_
  gas_file: gas_data_feed.gs
  python_function: null
  note: calcSemiconductorClusterGate_ 함수에 MARKET_WEIGHT_AWARE_CLUSTER_GATE_V1 구현
  cases:
  - id: mwacg_secular_leader_pass
    description: SECULAR_LEADER_RISK_ON에서 60% → cap=65% → CLUSTER_HOLD_ONLY
    inputs:
      holdings:
      - ticker: 005930
        weightPct: 40.0
        name: 삼성전자
      - ticker: '000660'
        weightPct: 20.0
        name: SK하이닉스
      marketRegime: SECULAR_LEADER_RISK_ON
      kospiSemiWeightPct: 0
    expected:
      gate_status: CLUSTER_HOLD_ONLY
      combined_pct: 60.0
      cap_pct: 65.0
    tolerance:
      combined_pct: 0.01
    provenance: HAND_COMPUTED
    note: SECULAR_LEADER cap=65. 60>=65*0.80=52(warn) but <65(cap) → CLUSTER_HOLD_ONLY
  - id: mwacg_risk_on_with_kospi_weight
    description: RISK_ON + KOSPI 55% 입력 → cap=71.5%, combined=63.77% → CLUSTER_OVERWEIGHT_WARN
    inputs:
      holdings:
      - ticker: 005930
        weightPct: 41.43
        name: 삼성전자
      - ticker: '000660'
        weightPct: 22.34
        name: SK하이닉스
      marketRegime: RISK_ON
      kospiSemiWeightPct: 55
    expected:
      gate_status: CLUSTER_OVERWEIGHT_WARN
      combined_pct: 63.77
      cap_pct: 71.5
    tolerance:
      combined_pct: 0.01
      cap_pct: 0.01
    provenance: HAND_COMPUTED
    note: 'cap=max(45,55*1.3)=71.5. warnThreshold=55*0.90=49.5.

      63.77 >= 49.5(warn) AND 63.77 < 71.5(cap) → CLUSTER_OVERWEIGHT_WARN.

      기존 CLUSTER_HOLD_ONLY에서 WARN으로 대폭 완화.

      '
- formula_id: LEADER_POSITION_WEIGHT_CAP_V1
  gas_function: calcSinglePositionWeightCap_
  gas_file: gas_data_feed.gs
  python_function: null
  note: calcSinglePositionWeightCap_ 함수에 LEADER_POSITION_WEIGHT_CAP_V1 구현
  cases:
  - id: leader_samsung_risk_on_kospi_input
    description: RISK_ON + Samsung KOSPI비중 30% → cap=max(40,30*1.7)=51 → 41.43% PASS
    inputs:
      holdings:
      - ticker: 005930
        weightPct: 41.43
        name: 삼성전자
      marketRegime: RISK_ON
      kospiSamsungWeightPct: 30
      kospiHynixWeightPct: 25
    expected:
      gate_status: PASS
    tolerance: {}
    provenance: HAND_COMPUTED
    note: Samsung RISK_ON cap=max(40,30*1.70)=max(40,51)=51. 41.43<51 → PASS
  - id: leader_hynix_pass_risk_on
    description: SK하이닉스 RISK_ON + KOSPI비중 25% → cap=max(22,25*1.8)=45 → 22.34% PASS
    inputs:
      holdings:
      - ticker: '000660'
        weightPct: 22.34
        name: SK하이닉스
      marketRegime: RISK_ON
      kospiSamsungWeightPct: 30
      kospiHynixWeightPct: 25
    expected:
      gate_status: PASS
    tolerance: {}
    provenance: HAND_COMPUTED
    note: SK하이닉스 RISK_ON cap=max(22,25*1.80)=max(22,45)=45. 22.34<45 → PASS
- formula_id: CAPITAL_STYLE_ALLOCATION_V1
  gas_function: null
  gas_file: null
  python_function: py_capital_style_allocation
  cases:
  - id: csa_scalp_high_tech_signal
    description: '단타 성향: RSI과매도+눌림목+Ret5D급락, DEEP 유동성'
    inputs:
      ticker: TEST
      style: SCALP
      rsi14: 30.0
      disparity: 2.0
      ret5d: -6.0
      volume: 1200000
      avg_vol5d: 1000000
      smart_money_score: 60.0
      fundamental_score: 55.0
      macro_event_score: 50.0
      liquidity_label: DEEP
    expected:
      conviction_score: 79.5
      recommended_pct: 5.0
    tolerance:
      conviction_score: 0.1
    provenance: CODE_DERIVED
    note: '기대값 79.5는 py_capital_style_allocation 실행 결과 복사 (2026-06-03).

      이전 HAND_COMPUTED 값 75.75는 현재 코드 공식과 불일치하여 갱신.

      '
  - id: csa_position_fundamental_driven
    description: '장기 성향: 펀더멘털 강세, MODERATE 유동성'
    inputs:
      ticker: TEST
      style: POSITION
      rsi14: 55.0
      disparity: 4.0
      ret5d: 2.0
      volume: 900000
      avg_vol5d: 1000000
      smart_money_score: 70.0
      fundamental_score: 85.0
      macro_event_score: 60.0
      liquidity_label: MODERATE
    expected:
      conviction_score: 69.98
      recommended_pct: 5.0
    tolerance:
      conviction_score: 0.1
    provenance: CODE_DERIVED
    note: '기대값 69.98은 py_capital_style_allocation 실행 결과 복사 (2026-06-03).

      이전 HAND_COMPUTED 값 67.28은 현재 코드 공식과 불일치하여 갱신.

      '
  - id: csa_frozen_liquidity_zero
    description: FROZEN 유동성 → conviction 강제 0
    inputs:
      ticker: TEST
      style: SWING
      rsi14: 40.0
      disparity: 5.0
      ret5d: 3.0
      volume: 500000
      avg_vol5d: 1000000
      smart_money_score: 80.0
      fundamental_score: 75.0
      macro_event_score: 70.0
      liquidity_label: FROZEN
    expected:
      conviction_score: 0.0
      recommended_pct: 0.0
    tolerance: {}
    provenance: SPEC_DERIVED
    note: FROZEN → liquidity_modifier=0.0 → conviction=raw×0=0 강제.
  - id: csa_macro_avoid_new_buy
    description: macro_gate=AVOID_NEW_BUY → macro_event_score 강제 0
    inputs:
      ticker: TEST
      style: MOMENTUM
      rsi14: 50.0
      disparity: 3.0
      ret5d: 1.0
      volume: 1000000
      avg_vol5d: 1000000
      smart_money_score: 65.0
      fundamental_score: 70.0
      macro_impact_score: 80.0
      macro_gate: AVOID_NEW_BUY
      liquidity_label: DEEP
    expected:
      conviction_score: 51.75
      recommended_pct: 3.0
    tolerance:
      conviction_score: 0.1
    provenance: HAND_COMPUTED
    note: "macro_gate=AVOID_NEW_BUY → macro_event_score=0.\ntech: 50 (RSI50정상, disp3.0\
      \ NOT < 3.0 so no +15, ret5d+1정상,\n      vol=1M NOT ≥1M×1.2 so no bonus). tech=50.\n\
      raw=0.15×50+0.25×65+0.40×70+0.20×0=7.5+16.25+28+0=51.75.\nconviction=51.75×1.0(DEEP)=51.75.\
      \ rec=3%(≥50).\n"
  - id: csa_pilot_boundary
    description: conviction=42(35≤42<50) → 파일럿 1.5%
    inputs:
      ticker: TEST
      style: SCALP
      rsi14: 50.0
      disparity: 8.0
      ret5d: 0.0
      volume: 500000
      avg_vol5d: 1000000
      smart_money_score: 30.0
      fundamental_score: 40.0
      macro_event_score: 40.0
      liquidity_label: DEEP
    expected:
      conviction_score: 46.5
      recommended_pct: 1.5
    tolerance:
      conviction_score: 0.1
    provenance: CODE_DERIVED
    note: '기대값 46.5는 py_capital_style_allocation 실행 결과 복사 (2026-06-03).

      이전 HAND_COMPUTED 값 42.0은 현재 코드 공식과 불일치하여 갱신.

      '
- formula_id: IMPUTED_DATA_EXPOSURE_GATE_V1
  python_function: tools/run_engine_audit_golden_cases_v1.py
  cases:
  - id: ideg_all_zeros
    description: all domains 0 except realized_outcome 0.667 → BLOCK
    inputs:
      domain_coverage:
        fundamental_core: 0.0
        realized_outcome: 0.6667
        trade_quality: 0.0
        pattern: 0.0
        alpha_eval: 0.0
      raw_cap: 93.0
    expected:
      gate_status: IMPUTED_DATA_BLOCK
      imputed_field_ratio: 0.8
      effective_confidence_honest: 48.4
    tolerance:
      imputed_field_ratio: 0.01
      effective_confidence_honest: 0.5
    provenance: HAND_COMPUTED
    spec_correct_src: spec/28_imputed_data_exposure_contract.yaml
    note: wc=0.30x0+0.30x0.6667+0=0.20, ifr=0.80, ech=93x0.52=48.36
  - id: ideg_full_coverage
    description: all domains 1.0 → PASS
    inputs:
      domain_coverage:
        fundamental_core: 1.0
        realized_outcome: 1.0
        trade_quality: 1.0
        pattern: 1.0
        alpha_eval: 1.0
      raw_cap: 93.0
    expected:
      gate_status: PASS
      imputed_field_ratio: 0.0
      effective_confidence_honest: 93.0
    tolerance:
      imputed_field_ratio: 0.01
      effective_confidence_honest: 0.1
    provenance: HAND_COMPUTED
    spec_correct_src: spec/28_imputed_data_exposure_contract.yaml
    note: wc=1.0, ifr=0, ech=93x1.0=93.0
- formula_id: TRAILING_STOP_PRICE_V1
  gas_function: calcTrailingStop_
  cases:
  - id: trailing_basic
    description: 350000 highest, ATR=8000, mult=2.0 → 334000
    inputs:
      highest_price_since_entry: 350000
      atr20: 8000
      trailing_atr_multiplier: 2.0
    expected:
      trailing_stop_price: 334000
    tolerance: {}
    provenance: HAND_COMPUTED
    spec_correct_src: spec/13_formula_registry.yaml:TRAILING_STOP_PRICE_V1
    note: 350000 - 8000x2.0 = 334000
- formula_id: EXPECTED_EDGE_V1
  gas_function: calcExpectedEdge_
  cases:
  - id: edge_2r_conf065
    description: R=2.0 confidence=0.65 → edge=1.30
    inputs:
      target_price: 120000
      entry_price: 100000
      stop_price: 90000
      bayesian_confidence: 0.65
    expected:
      expected_edge: 1.3
    tolerance:
      expected_edge: 0.01
    provenance: HAND_COMPUTED
    spec_correct_src: spec/13_formula_registry.yaml:EXPECTED_EDGE_V1
    note: 20000/10000 x 0.65 = 1.30
- formula_id: TP_VALIDITY_CHECK_V1
  gas_function: checkTpValidity_
  cases:
  - id: tp_valid
    description: tp 140000 > current 120000 → valid
    inputs:
      tp_price: 140000
      current_price: 120000
    expected:
      tp_validated_price: 140000
      tp_state: PENDING
    tolerance: {}
    provenance: HAND_COMPUTED
    spec_correct_src: spec/13b_harness_formulas.yaml:TP_VALIDITY_CHECK_V1
    note: 140000 > 120000 → valid
  - id: tp_triggered
    description: tp 100000 < current 120000 → null (triggered)
    inputs:
      tp_price: 100000
      current_price: 120000
    expected:
      tp_validated_price: null
      tp_state: TP1_ALREADY_TRIGGERED
    tolerance: {}
    provenance: HAND_COMPUTED
    spec_correct_src: spec/13b_harness_formulas.yaml:TP_VALIDITY_CHECK_V1
    note: 100000 < 120000 → already triggered
- formula_id: RS_RATIO_V1
  gas_function: calcRsRatio_
  cases:
  - id: rs_outperform
    description: stock+8 KOSPI+4 → rs=2.0
    inputs:
      stock_close_5d_return: 8.0
      kospi_close_5d_return: 4.0
    expected:
      rs_ratio: 2.0
    tolerance:
      rs_ratio: 0.001
    provenance: HAND_COMPUTED
    spec_correct_src: spec/13_formula_registry.yaml:RS_RATIO_V1
    note: 8.0/4.0=2.0
- formula_id: RATCHET_TRAILING_AUTO_V1
  gas_function: calcRatchetTrailingAuto_
  cases:
  - id: pl20_atr_wins
    description: ATR trailing 302000 > ratchet 280000 → 302000
    inputs:
      profit_lock_stage: PROFIT_LOCK_20
      ratchet_stop: 280000
      highest_close: 320000
      atr20: 12000
    expected:
      auto_trailing_stop: 302000
    tolerance: {}
    provenance: HAND_COMPUTED
    spec_correct_src: spec/13b_harness_formulas.yaml:RATCHET_TRAILING_AUTO_V1
    note: max(280000, 320000-18000)=max(280000,302000)=302000
  - id: pl20_ratchet_wins
    description: ratchet 310000 > ATR trailing 302000 → 310000
    inputs:
      profit_lock_stage: PROFIT_LOCK_20
      ratchet_stop: 310000
      highest_close: 320000
      atr20: 12000
    expected:
      auto_trailing_stop: 310000
    tolerance: {}
    provenance: HAND_COMPUTED
    spec_correct_src: spec/13b_harness_formulas.yaml:RATCHET_TRAILING_AUTO_V1
    note: max(310000, 302000)=310000
- formula_id: STOP_PRICE_CORE_V1
  gas_function: calcStopPrice_
  cases:
  - id: stop_atr_wins
    description: ATR stop higher → use ATR stop
    inputs:
      entry_price: 100000
      atr20: 5000
      atr_multiplier: 1.5
    expected:
      stop_price: 92500
    tolerance: {}
    provenance: HAND_COMPUTED
    spec_correct_src: spec/13_formula_registry.yaml:STOP_PRICE_CORE_V1
    note: max(100000x0.92, 100000-5000x1.5)=max(92000,92500)=92500
  - id: stop_8pct_wins
    description: ATR stop 95500 > floor 92000 → use 95500
    inputs:
      entry_price: 100000
      atr20: 3000
      atr_multiplier: 1.5
    expected:
      stop_price: 95500
    tolerance: {}
    provenance: HAND_COMPUTED
    spec_correct_src: spec/13_formula_registry.yaml:STOP_PRICE_CORE_V1
    note: max(100000*0.92=92000, 100000-3000*1.5=95500)=95500
- formula_id: TARGET_CASH_PCT_V1
  gas_function: calcTargetCashPct_
  cases:
  - id: target_cash_mrs5
    description: MRS=5 (overheated) → cash target=12.5 vs floor=10 → 12.5
    inputs:
      market_risk_score: 5
      cash_floor_regime_min_pct: 10
    expected:
      target_cash_pct: 12.5
    tolerance:
      target_cash_pct: 0.1
    provenance: HAND_COMPUTED
    spec_correct_src: spec/13_formula_registry.yaml:TARGET_CASH_PCT_V1
    note: max(5+(5/10)*15, 10)=max(5+7.5,10)=max(12.5,10)=12.5
  - id: target_cash_mrs0
    description: MRS=0 (normal) → max(5,7)=7
    inputs:
      market_risk_score: 0
      cash_floor_regime_min_pct: 7
    expected:
      target_cash_pct: 7
    tolerance:
      target_cash_pct: 0.1
    provenance: HAND_COMPUTED
    spec_correct_src: spec/13_formula_registry.yaml:TARGET_CASH_PCT_V1
    note: max(5+(0/10)*15, 7)=max(5,7)=7
- formula_id: FLOW_CREDIT_V1
  gas_function: calcFlowCredit_
  cases:
  - id: flow_credit_all_one
    description: All components 1.0 → flow_credit=1.0
    inputs:
      c1_price_action: 1.0
      c2_volume_action: 1.0
      c3_flow_action: 1.0
    expected:
      flow_credit: 1.0
    tolerance:
      flow_credit: 0.001
    provenance: HAND_COMPUTED
    spec_correct_src: spec/13_formula_registry.yaml:FLOW_CREDIT_V1
    note: 1.0x0.30+1.0x0.30+1.0x0.40=0.30+0.30+0.40=1.0
  - id: flow_credit_mixed
    description: C1=0.8 C2=0.5 C3=0.3 → 0.51
    inputs:
      c1_price_action: 0.8
      c2_volume_action: 0.5
      c3_flow_action: 0.3
    expected:
      flow_credit: 0.51
    tolerance:
      flow_credit: 0.001
    provenance: HAND_COMPUTED
    spec_correct_src: spec/13_formula_registry.yaml:FLOW_CREDIT_V1
    note: 0.8x0.30+0.5x0.30+0.3x0.40=0.24+0.15+0.12=0.510
- formula_id: MARKET_RISK_SCORE_V1
  gas_function: calcMarketRiskScore_
  cases:
  - id: mrs_capped
    description: Sum exceeds 10 → capped at 10
    inputs:
      vix_score: 3
      kospi_score: 3
      usd_krw_score: 2
      usd_jpy_score: 2
      credit_score: 2
    expected:
      market_risk_score: 10
    tolerance: {}
    provenance: HAND_COMPUTED
    spec_correct_src: spec/13_formula_registry.yaml:MARKET_RISK_SCORE_V1
    note: min(10, 3+3+2+2+2)=min(10,12)=10
  - id: mrs_normal
    description: Sum=5 (normal market)
    inputs:
      vix_score: 1
      kospi_score: 1
      usd_krw_score: 1
      usd_jpy_score: 1
      credit_score: 1
    expected:
      market_risk_score: 5
    tolerance: {}
    provenance: HAND_COMPUTED
    spec_correct_src: spec/13_formula_registry.yaml:MARKET_RISK_SCORE_V1
    note: min(10, 1+1+1+1+1)=min(10,5)=5
- formula_id: PORTFOLIO_BETA_V1
  gas_function: calcPortfolioBeta_
  cases:
  - id: pbeta_two_stocks
    description: Two stocks weighted beta
    inputs:
      holdings:
      - beta: 1.2
        market_value: 60000000
      - beta: 0.8
        market_value: 40000000
      total_equity_value: 100000000
    expected:
      portfolio_beta: 1.04
    tolerance:
      portfolio_beta: 0.01
    provenance: HAND_COMPUTED
    spec_correct_src: spec/13_formula_registry.yaml:PORTFOLIO_BETA_V1
    note: (1.2x60000000 + 0.8x40000000)/100000000 = (72M+32M)/100M = 1.04
- formula_id: RISK_BUDGET_CASCADE_V1
  gas_function: calcRiskBudgetCascade_
  cases:
  - id: risk_budget_normal
    description: Normal conditions → budget maintained
    inputs:
      base_risk_budget: 0.007
      net_return_feedback_multiplier: 1.0
      performance_brake_multiplier: 1.0
    expected:
      risk_budget: 0.007
    tolerance:
      risk_budget: 0.0001
    provenance: HAND_COMPUTED
    spec_correct_src: spec/13_formula_registry.yaml:RISK_BUDGET_CASCADE_V1
    note: 0.007 x 1.0 x 1.0 = 0.007
  - id: risk_budget_reduced
    description: Poor performance → reduced budget
    inputs:
      base_risk_budget: 0.007
      net_return_feedback_multiplier: 0.75
      performance_brake_multiplier: 0.8
    expected:
      risk_budget: 0.0042
    tolerance:
      risk_budget: 0.0001
    provenance: HAND_COMPUTED
    spec_correct_src: spec/13_formula_registry.yaml:RISK_BUDGET_CASCADE_V1
    note: 0.007 x 0.75 x 0.80 = 0.0042
- formula_id: MEAN_REVERSION_GATE_V1
  python_function: compute_mean_reversion_gate
  cases:
  - id: mrg_overextended
    description: close 10% above ma20
    inputs:
      close_price: 110000
      ma20: 100000
    expected:
      deviation_ratio: 1.1
      gate: OVEREXTENDED
    tolerance:
      deviation_ratio: 0.001
    provenance: HAND_COMPUTED
    spec_correct_src: spec/13_formula_registry.yaml:MEAN_REVERSION_GATE_V1
    note: 110000/100000=1.10 OVEREXTENDED
  - id: mrg_normal
    description: close 5% above ma20
    inputs:
      close_price: 105000
      ma20: 100000
    expected:
      deviation_ratio: 1.05
      gate: NORMAL
    tolerance:
      deviation_ratio: 0.001
    provenance: HAND_COMPUTED
    spec_correct_src: spec/13_formula_registry.yaml:MEAN_REVERSION_GATE_V1
    note: 105000/100000=1.05 NORMAL
- formula_id: T1_FORCED_SELL_RISK_V1
  python_function: compute_t1_forced_sell_risk
  cases:
  - id: t1_moderate
    description: sell+timing = 65 MODERATE
    inputs:
      sell_action_active: 1
      timing_exit_ge_50: 1
      rw_ge_2: 0
      distribution_ge_70: 0
    expected:
      t1_forced_sell_risk_score: 65
      gate: MODERATE
    tolerance: {}
    provenance: HAND_COMPUTED
    spec_correct_src: spec/13_formula_registry.yaml:T1_FORCED_SELL_RISK_V1
    note: 1x40+1x25=65 MODERATE
  - id: t1_low
    description: no signals = 0 LOW
    inputs:
      sell_action_active: 0
      timing_exit_ge_50: 0
      rw_ge_2: 0
      distribution_ge_70: 0
    expected:
      t1_forced_sell_risk_score: 0
      gate: LOW
    tolerance: {}
    provenance: HAND_COMPUTED
    spec_correct_src: spec/13_formula_registry.yaml:T1_FORCED_SELL_RISK_V1
    note: all zero = 0 LOW
- formula_id: SELL_CONFLICT_AWARE_RECOMMENDATION_V1
  python_function: compute_sell_conflict_recommendation
  cases:
  - id: scr_sell_priority
    description: sell_signal=1 gives 55 SELL_PRIORITY
    inputs:
      sell_signal_active: 1
      cash_preserve_active: 0
      no_add_gate: 0
    expected:
      conflict_score: 55
      recommendation: SELL_PRIORITY
    tolerance: {}
    provenance: HAND_COMPUTED
    spec_correct_src: spec/13_formula_registry.yaml:SELL_CONFLICT_AWARE_RECOMMENDATION_V1
    note: 1x55=55 SELL_PRIORITY
  - id: scr_hold
    description: no signals = 0 HOLD
    inputs:
      sell_signal_active: 0
      cash_preserve_active: 0
      no_add_gate: 0
    expected:
      conflict_score: 0
      recommendation: HOLD
    tolerance: {}
    provenance: HAND_COMPUTED
    spec_correct_src: spec/13_formula_registry.yaml:SELL_CONFLICT_AWARE_RECOMMENDATION_V1
    note: 0 HOLD
- formula_id: SEMICONDUCTOR_CLUSTER_SYNC_V1
  python_function: compute_semiconductor_cluster_sync
  cases:
  - id: semi_mandatory
    description: 80 > 35*2=70 mandatory
    inputs:
      cluster_pct: 80.0
      cluster_limit_pct: 35.0
    expected:
      is_mandatory: true
      gate: MANDATORY_REDUCE
    tolerance: {}
    provenance: HAND_COMPUTED
    spec_correct_src: spec/13_formula_registry.yaml:SEMICONDUCTOR_CLUSTER_SYNC_V1
    note: 80>70 mandatory
  - id: semi_pass
    description: 60 <= 35*2=70 PASS
    inputs:
      cluster_pct: 60.0
      cluster_limit_pct: 35.0
    expected:
      is_mandatory: false
      gate: PASS
    tolerance: {}
    provenance: HAND_COMPUTED
    spec_correct_src: spec/13_formula_registry.yaml:SEMICONDUCTOR_CLUSTER_SYNC_V1
    note: 60<=70 PASS
- formula_id: GOAL_RETIREMENT_V1
  python_function: compute_goal_retirement
  cases:
  - id: goal_80pct
    description: 400M / 500M = 80%
    inputs:
      total_asset_krw: 400000000
      goal_krw: 500000000
    expected:
      goal_achievement_pct: 80.0
      goal_status: IN_PROGRESS
    tolerance:
      goal_achievement_pct: 0.1
    provenance: HAND_COMPUTED
    spec_correct_src: spec/13_formula_registry.yaml:GOAL_RETIREMENT_V1
    note: round(400M/500M*1000)/10=80.0
  - id: goal_achieved
    description: 500M reached = 100% ACHIEVED
    inputs:
      total_asset_krw: 500000000
      goal_krw: 500000000
    expected:
      goal_achievement_pct: 100.0
      goal_status: ACHIEVED
    tolerance:
      goal_achievement_pct: 0.1
    provenance: HAND_COMPUTED
    spec_correct_src: spec/13_formula_registry.yaml:GOAL_RETIREMENT_V1
    note: 500M/500M=100%
- formula_id: DIVERGENCE_SCORE_V1
  python_function: compute_divergence_score
  cases:
  - id: divergence_zero_below_ma20
    description: price below MA20 = score 0 NEUTRAL
    inputs:
      price_above_ma20: 0
      foreign_net_sell: 80.0
      institution_net_sell: 60.0
      vol_surge: 40.0
    expected:
      divergence_score: 0.0
      gate: NEUTRAL
    tolerance:
      divergence_score: 0.1
    provenance: HAND_COMPUTED
    spec_correct_src: spec/13_formula_registry.yaml:DIVERGENCE_SCORE_V1
    note: 0*(..)=0 NEUTRAL
- formula_id: VALUE_PRESERVATION_SCORER_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: value_preservation_scorer_v1_reference
    description: GAS 구현 기준 문서화. 종목별 가치 훼손 점수(value_damage_score 0~100) + 반등 잠재력(rebound_pote
    inputs:
      Close: 1000000
      MA20: 1000000
      MA60: 1000000
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13_formula_registry.yaml:VALUE_PRESERVATION_SCORER_V1
    note: GAS-only formula. Python mirror not implemented.
- formula_id: RS_VERDICT_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: rs_verdict_v1_reference
    description: GAS 구현 기준 문서화. 종목의 10일 수익률을 KOSPI 10일 수익률과 비교해 초과 수익률(excess_ret_10d)을
      계산하고
    inputs:
      price.ret10D: 0.5
      globalKospiRet10D_: 0.5
      rw_partial: 1.0
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13_formula_registry.yaml:RS_VERDICT_V1
    note: GAS-only formula. Python mirror not implemented.
- formula_id: ROUTING_SERVING_DECISION_TRACE_V2
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: routing_serving_decision_trace_v2_reference
    description: GAS 구현 기준 문서화. 라우팅→서빙→게이트 경로를 단일 trace JSON으로 고정해 사후감사 가능성 확보.
    inputs:
      routing_trace_json: 1.0
      export_gate_json: 1.0
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13_formula_registry.yaml:ROUTING_SERVING_DECISION_TRACE_V2
    note: GAS-only formula. Python mirror not implemented.
- formula_id: LIQUIDITY_FLOW_SIGNAL_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: liquidity_flow_signal_v1_reference
    description: GAS 구현 기준 문서화. AvgTradeValue_20D_M 기반으로 종목별 유동성을 DEEP/NORMAL/THIN/FROZEN으로
    inputs: {}
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13_formula_registry.yaml:LIQUIDITY_FLOW_SIGNAL_V1
    note: GAS-only formula. Python mirror not implemented.
- formula_id: CASH_RATIOS_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: cash_ratios_v1_reference
    description: GAS 구현 기준 문서화. 현금비중·매수가능현금·거래 후 현금비중 계산 (D+2 정산현금 단독 기준)
    inputs:
      settlement_cash: 1000000
      reserved_order_amount: 1000000
      planned_buy_amount: 1000000
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13_formula_registry.yaml:CASH_RATIOS_V1
    note: GAS-only formula. Python mirror not implemented.
- formula_id: CLA_REGIME_EXIT_CONDITION_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: cla_regime_exit_condition_v1_reference
    description: GAS 구현 기준 문서화. CONCENTRATED_LEADER_ADVANCE 국면의 종료 조건을 결정론적으로 탐지한다.
      CLA 활성 중
    inputs:
      ticker: 1.0
      rs_verdict: 1.0
      brt_verdict: 1.0
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13_formula_registry.yaml:CLA_REGIME_EXIT_CONDITION_V1
    note: GAS-only formula. Python mirror not implemented.
- formula_id: REPLACEMENT_ALPHA_GATE_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: replacement_alpha_gate_v1_reference
    description: GAS 구현 기준 문서화. 위성 신규매수 전 코어 대비 알파 우위 여부를 기계적으로 검증한다. 코어보다 약한 위성에
      현금을 투입하는 '
    inputs:
      rs_verdict: 1.0
      ss001_grade: 1.0
      excess_ret_10d: 0.5
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13_formula_registry.yaml:REPLACEMENT_ALPHA_GATE_V1
    note: GAS-only formula. Python mirror not implemented.
- formula_id: FINAL_JUDGMENT_GATE_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: final_judgment_gate_v1_reference
    description: GAS 구현 기준 문서화. 판단 결정론 계층 — 키스톤. 모든 게이트·신호 JSON + _harness_context를
      읽어 종목별 단
    inputs: {}
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13_formula_registry.yaml:FINAL_JUDGMENT_GATE_V1
    note: GAS-only formula. Python mirror not implemented.
- formula_id: GROWTH_RATE_SIGNAL_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: growth_rate_signal_v1_reference
    description: GAS 구현 기준 문서화. EPS YoY / 매출 YoY 기반 성장률 시그널을 결정론적으로 산출한다. HYPER_GROWTH/GROWT
    inputs: {}
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13_formula_registry.yaml:GROWTH_RATE_SIGNAL_V1
    note: GAS-only formula. Python mirror not implemented.
- formula_id: SATELLITE_LIFECYCLE_GATE_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: satellite_lifecycle_gate_v1_reference
    description: GAS 구현 기준 문서화. 위성 종목에 WATCH/PILOT/CONFIRMED/REVIEW/EXIT 5단계 라이프사이클을
      부여한다. 각
    inputs:
      ticker: 1.0
      composite_verdict: 1.0
      brt_verdict: 1.0
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13_formula_registry.yaml:SATELLITE_LIFECYCLE_GATE_V1
    note: GAS-only formula. Python mirror not implemented.
- formula_id: FLOW_ACCELERATION_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: flow_acceleration_v1_reference
    description: GAS 구현 기준 문서화. 가격 상승 중 외국인 매수 강도가 20D 평균 대비 급격히 둔화되는 에너지 소진(Distribution)
      초
    inputs:
      frg_5d_sh: 1.0
      frg_20d_sh: 1.0
      close_price: 1000000
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13_formula_registry.yaml:FLOW_ACCELERATION_V1
    note: GAS-only formula. Python mirror not implemented.
- formula_id: SMART_CASH_RECOVERY_V3
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: smart_cash_recovery_v3_reference
    description: GAS 구현 기준 문서화. 국면별 동적 rebound_factor + 유동성 라벨(DEEP/NORMAL/THIN/FROZEN)
      기반으로
    inputs:
      value_preservation_scorer_v1_json: 1.0
      scrs_v2_json: 1.0
      market_regime_state: 1.0
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13_formula_registry.yaml:SMART_CASH_RECOVERY_V3
    note: GAS-only formula. Python mirror not implemented.
- formula_id: PORTFOLIO_ALPHA_CONFIDENCE_PER_TICKER_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: portfolio_alpha_confidence_per_ticker_v1_reference
    description: GAS 구현 기준 문서화. 기존 포트폴리오 전체 단일값 PAC(-90.7)를 종목별 분산 PAC로 교체. entry_freshness(
    inputs: {}
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13_formula_registry.yaml:PORTFOLIO_ALPHA_CONFIDENCE_PER_TICKER_V1
    note: GAS-only formula. Python mirror not implemented.
- formula_id: CASH_RECOVERY_OPTIMIZER_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: cash_recovery_optimizer_v1_reference
    description: GAS 구현 기준 문서화. 목표 현금 회복액에 최소 주식가치 훼손으로 도달하는 최적 매도 조합을 결정론적 산출. LLM이
      "63주+24
    inputs:
      cash_shortfall_target_krw: 1000000
      cash_shortfall_min_krw: 1000000
      sell_candidates_json: 1.0
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13_formula_registry.yaml:CASH_RECOVERY_OPTIMIZER_V1
    note: GAS-only formula. Python mirror not implemented.
- formula_id: FUNDAMENTAL_QUALITY_GATE_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: fundamental_quality_gate_v1_reference
    description: GAS 구현 기준 문서화. 펀더멘털 품질(ROE/이익성장/부채/현금흐름/밸류)을 결정론적으로 점수화해 BUY 허용 여부를
      잠금.
    inputs:
      roe_pct: 1.0
      op_income_growth_pct: 1.0
      debt_ratio_pct: 1.0
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13_formula_registry.yaml:FUNDAMENTAL_QUALITY_GATE_V1
    note: GAS-only formula. Python mirror not implemented.
- formula_id: FUNDAMENTAL_MULTIFACTOR_V3
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: fundamental_multifactor_v3_reference
    description: GAS 구현 기준 문서화. ROE(25) + OPM(20) + OCF(15) + FCF(15) + Debt(10) +
      Valuation
    inputs: {}
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13_formula_registry.yaml:FUNDAMENTAL_MULTIFACTOR_V3
    note: GAS-only formula. Python mirror not implemented.
- formula_id: INTRADAY_ACTION_MATRIX_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: intraday_action_matrix_v1_reference
    description: GAS 구현 기준 문서화. 장중 시각(capture_time)에 따라 허용·금지 액션을 테이블로 고정한다. 09:31
      캡처임에도 전체
    inputs:
      capture_time: 1.0
      market_date: 1.0
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13_formula_registry.yaml:INTRADAY_ACTION_MATRIX_V1
    note: GAS-only formula. Python mirror not implemented.
- formula_id: CASHFLOW_QUALITY_SIGNAL_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: cashflow_quality_signal_v1_reference
    description: GAS 구현 기준 문서화. OCF/FCF 기반 현금흐름 안정성을 결정론적으로 라벨링한다. ROBUST/STABLE/VOLATILE/RI
    inputs: {}
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13_formula_registry.yaml:CASHFLOW_QUALITY_SIGNAL_V1
    note: GAS-only formula. Python mirror not implemented.
- formula_id: MARKET_SHARE_SIGNAL_V2
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: market_share_signal_v2_reference
    description: GAS 구현 기준 문서화. 실매출 점유율 데이터 없는 환경에서 AvgTradeValue_20D_M 백분위 + 외인/기관
      수급 + 20일
    inputs: {}
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13_formula_registry.yaml:MARKET_SHARE_SIGNAL_V2
    note: GAS-only formula. Python mirror not implemented.
- formula_id: SELL_WATERFALL_ENGINE_V2
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: sell_waterfall_engine_v2_reference
    description: GAS 구현 기준 문서화. V1 4단계 유지 + 호가단위 슬리피지(bps) 시뮬, TWAP/지정가 분할(유동성기반),
      부분체결 잔량 자
    inputs: {}
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13_formula_registry.yaml:SELL_WATERFALL_ENGINE_V2
    note: GAS-only formula. Python mirror not implemented.
- formula_id: OVERHANG_PRESSURE_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: overhang_pressure_v1_reference
    description: GAS 구현 기준 문서화. 외국인 매도 속도가 최근 20D 평균 대비 급가속하면서 거래대금이 감소하면 오버행(대기 매도
      물량) 누적으로
    inputs:
      frg_5d_sh: 1.0
      frg_20d_sh: 1.0
      volume: 1.0
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13_formula_registry.yaml:OVERHANG_PRESSURE_V1
    note: GAS-only formula. Python mirror not implemented.
- formula_id: TOTAL_HEAT_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: total_heat_v1_reference
    description: GAS 구현 기준 문서화. 손절 기준 총 위험노출 계산
    inputs:
      average_cost: 1000000
      stop_price: 1000000
      quantity: 1.0
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13_formula_registry.yaml:TOTAL_HEAT_V1
    note: GAS-only formula. Python mirror not implemented.
- formula_id: SATELLITE_AGGREGATE_PNL_GATE_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: satellite_aggregate_pnl_gate_v1_reference
    description: GAS 구현 기준 문서화. 위성 합산 평가손익이 코어 수익을 잠식하는 정도를 추적해 위성 전략 실패를 감지한다.
    inputs:
      position_class: 1.0
      profit_loss: 1000000
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13_formula_registry.yaml:SATELLITE_AGGREGATE_PNL_GATE_V1
    note: GAS-only formula. Python mirror not implemented.
- formula_id: PROFIT_LOCK_RATCHET_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: profit_lock_ratchet_v1_reference
    description: GAS 구현 기준 문서화. 분할 익절 단계별 손절선 상향(래칫) 공식. tier_1 익절 완료 후 손절선을 본절(average_cost
    inputs:
      average_cost: 1000000
      tier_completed: 1.0
      highest_price_since_entry: 1000000
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13_formula_registry.yaml:PROFIT_LOCK_RATCHET_V1
    note: GAS-only formula. Python mirror not implemented.
- formula_id: RS_MOMENTUM_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: rs_momentum_v1_reference
    description: GAS 구현 기준 문서화. 상대강도(RS)와 수급 가속도를 측정하여 상투 진입 방지 및 후발주(Laggard) 조기
      식별
    inputs:
      close_price: 1000000
      ma20: 1000000
      avg_trade_value_5d: 1000000
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13_formula_registry.yaml:RS_MOMENTUM_V1
    note: GAS-only formula. Python mirror not implemented.
- formula_id: STOP_PROPOSAL_LADDER_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: stop_proposal_ladder_v1_reference
    description: GAS 구현 기준 문서화. 사용자 판단용 proposal_reference_sheet에 표시할 손절 1/2/3 가격·수량
      래더 산출.
    inputs:
      position_class: 1.0
      holding_quantity: 1.0
      proposed_quantity: 1.0
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13_formula_registry.yaml:STOP_PROPOSAL_LADDER_V1
    note: GAS-only formula. Python mirror not implemented.
- formula_id: FUNDAMENTAL_RAW_INGEST_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: fundamental_raw_ingest_v1_reference
    description: GAS 구현 기준 문서화. data_feed(Forward_PE/PBR/EPS)와 네이버 금융 fallback을 통해
      보유 종목의 펀더
    inputs: {}
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13_formula_registry.yaml:FUNDAMENTAL_RAW_INGEST_V1
    note: GAS-only formula. Python mirror not implemented.
- formula_id: CANONICAL_METRICS_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: canonical_metrics_v1_reference
    description: GAS 구현 기준 문서화. spec/25_canonical_metrics_registry.yaml에 정의된 논리 지표(cluster_p
    inputs: {}
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13_formula_registry.yaml:CANONICAL_METRICS_V1
    note: GAS-only formula. Python mirror not implemented.
- formula_id: CROSS_SECTION_CONSISTENCY_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: cross_section_consistency_v1_reference
    description: GAS 구현 기준 문서화. operational_report.json 섹션 markdown을 파싱해 CANONICAL_METRICS_V
    inputs: {}
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13_formula_registry.yaml:CROSS_SECTION_CONSISTENCY_V1
    note: GAS-only formula. Python mirror not implemented.
- formula_id: LLM_SERVING_CONSTRAINT_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: llm_serving_constraint_v1_reference
    description: GAS 구현 기준 문서화. LLM이 보고서 작성 시 침범 금지 영역 8개를 명시적으로 잠금. HS011 확장판. 30년
      실전 전문가의
    inputs:
      harness_context: 1.0
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13_formula_registry.yaml:LLM_SERVING_CONSTRAINT_V1
    note: GAS-only formula. Python mirror not implemented.
- formula_id: FINANCIAL_HEALTH_SCORE_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: financial_health_score_v1_reference
    description: GAS 구현 기준 문서화. ROE·영업이익률·부채비율·FCF를 결합해 종목의 재무 건전성을 0~20점으로 정량화. 수급·모멘텀
      중심 편
    inputs:
      roe_pct: 1.0
      operating_margin_pct: 1.0
      debt_to_equity: 0.5
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13_formula_registry.yaml:FINANCIAL_HEALTH_SCORE_V1
    note: GAS-only formula. Python mirror not implemented.
- formula_id: SELL_WATERFALL_ENGINE_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: sell_waterfall_engine_v1_reference
    description: GAS 구현 기준 문서화. "주식가치를 크게 훼손하지 않으면서 반등 시 수익까지 고려"하는 현금확보 매도 표준화. K2(50/50
      분할
    inputs:
      cash_recovery_plan_json: 1.0
      emergency_full_sell: 1.0
      oversold_gate: 1.0
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13_formula_registry.yaml:SELL_WATERFALL_ENGINE_V1
    note: GAS-only formula. Python mirror not implemented.
- formula_id: LLM_NARRATIVE_TEMPLATE_LOCK_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: llm_narrative_template_lock_v1_reference
    description: GAS 구현 기준 문서화. operational_report.json 각 section.markdown에서 금지 어휘(같다/약간/곧/강
    inputs: {}
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13_formula_registry.yaml:LLM_NARRATIVE_TEMPLATE_LOCK_V1
    note: GAS-only formula. Python mirror not implemented.
- formula_id: BLANK_CELL_AUDIT_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: blank_cell_audit_v1_reference
    description: GAS 구현 기준 문서화. 보고서 GFM 표의 빈 셀·일률 stub 라벨을 감사하여 셀-레벨 결정론 충족 여부를 판정한다.
      금지 일률값
    inputs:
      operational_report_json: 1.0
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13_formula_registry.yaml:BLANK_CELL_AUDIT_V1
    note: GAS-only formula. Python mirror not implemented.
- formula_id: REGIME_TRIM_WEIGHT_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: regime_trim_weight_v1_ref
    description: GAS 하네스 구현 문서화. 시장 국면(market_regime_state) 기반으로 위성·주도주의 감축 비율 범위를
      결정론적 산출. L
    inputs: {}
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13b_harness_formulas.yaml:REGIME_TRIM_WEIGHT_V1
    note: GAS-only harness formula.
- formula_id: SECULAR_LEADER_REGIME_GATE_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: secular_leader_regime_gate_v1_ref
    description: GAS 하네스 구현 문서화. 삼성전자(005930)·SK하이닉스(000660)의 secular_leader_profit_lock
      발동 조
    inputs: {}
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13b_harness_formulas.yaml:SECULAR_LEADER_REGIME_GATE_V1
    note: GAS-only harness formula.
- formula_id: TRIM_PLAN_MIN_CASH_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: trim_plan_min_cash_v1_ref
    description: GAS 하네스 구현 문서화. 현금 부족액(CASH_SHORTFALL_V1) 해소를 위한 종목별 TRIM 계획을 H2
      매도우선순위 기반으로
    inputs: {}
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13b_harness_formulas.yaml:TRIM_PLAN_MIN_CASH_V1
    note: GAS-only harness formula.
- formula_id: ALPHA_LEAD_SCORE_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: alpha_lead_score_v1_ref
    description: GAS 하네스 구현 문서화. 주도 섹터·상대강도·수급가속·거래대금·과열도를 결합해 선행 파일럿 진입 가능성을 0~100
      점수와 상태로 확
    inputs: {}
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13b_harness_formulas.yaml:ALPHA_LEAD_SCORE_V1
    note: GAS-only harness formula.
- formula_id: FOLLOW_THROUGH_CONFIRM_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: follow_through_confirm_v1_ref
    description: GAS 하네스 구현 문서화. 돌파 이후 1~3거래일 내 가격 유지·거래대금 과열 완화·수급 유지 여부를 확인해 본진입,
      대기, 실패를 결
    inputs: {}
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13b_harness_formulas.yaml:FOLLOW_THROUGH_CONFIRM_V1
    note: GAS-only harness formula.
- formula_id: DISTRIBUTION_RISK_SCORE_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: distribution_risk_score_v1_ref
    description: GAS 하네스 구현 문서화. 가격 유지 또는 상승 중 스마트머니 이탈, 거래대금 둔화, 윗꼬리, 낮은 flow_credit,
      섹터 대비
    inputs: {}
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13b_harness_formulas.yaml:DISTRIBUTION_RISK_SCORE_V1
    note: GAS-only harness formula.
- formula_id: PROFIT_PRESERVATION_STATE_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: profit_preservation_state_v1_ref
    description: GAS 하네스 구현 문서화. 수익률, ATR, 고점 대비 하락, 수급 훼손, 분산 위험을 이용해 수익 보호 단계를 분류하고
      래칫·트레일링
    inputs: {}
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13b_harness_formulas.yaml:PROFIT_PRESERVATION_STATE_V1
    note: GAS-only harness formula.
- formula_id: REBOUND_SELL_TRIGGER_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: rebound_sell_trigger_v1_ref
    description: GAS 하네스 구현 문서화. 과매도 현금확보 후보의 잔여 매도를 반등 조건 충족 시점으로 지연한다.
    inputs: {}
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13b_harness_formulas.yaml:REBOUND_SELL_TRIGGER_V1
    note: GAS-only harness formula.
- formula_id: EXECUTION_QUALITY_GUARD_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: execution_quality_guard_v1_ref
    description: GAS 하네스 구현 문서화. 주문금액/거래대금/스프레드/변동성을 이용해 체결 품질과 분할 필요 여부를 검증한다.
    inputs: {}
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13b_harness_formulas.yaml:EXECUTION_QUALITY_GUARD_V1
    note: GAS-only harness formula.
- formula_id: SELL_QUANTITY_ALLOCATOR_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: sell_quantity_allocator_v1_ref
    description: GAS 하네스 구현 문서화. 현금 부족액, 매도우선순위, 실행스타일, cap을 반영해 정수 매도수량을 확정한다.
    inputs: {}
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13b_harness_formulas.yaml:SELL_QUANTITY_ALLOCATOR_V1
    note: GAS-only harness formula.
- formula_id: K3_REGIME_SELL_PRIORITY_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: k3_regime_sell_priority_v1_ref
    description: GAS 하네스 구현 문서화. H2 정적 순위에 시장 국면(regime) 신호를 오버레이하여 동적 우선순위를 부여한다.
      EVENT_SHOC
    inputs: {}
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13b_harness_formulas.yaml:K3_REGIME_SELL_PRIORITY_V1
    note: GAS-only harness formula.
- formula_id: PRE_DISTRIBUTION_EARLY_WARNING_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: pre_distribution_early_warning_ref
    description: GAS 하네스 구현 문서화. DISTRIBUTION_RISK_SCORE_V1에 두 가지 선행경보 신호를 추가한다. (1)
      신고점 근접 +
    inputs: {}
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13b_harness_formulas.yaml:PRE_DISTRIBUTION_EARLY_WARNING_V1
    note: GAS-only harness formula.
- formula_id: PORTFOLIO_BETA_GATE_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: portfolio_beta_gate_v1_ref
    description: GAS 하네스 구현 문서화. 보유 종목 가중평균 베타(beta_proxy = ret5d/kospiRet5d)를 산출하고
      국면별 상한과 비
    inputs: {}
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13b_harness_formulas.yaml:PORTFOLIO_BETA_GATE_V1
    note: GAS-only harness formula.
- formula_id: TP_QUANTITY_LADDER_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: tp_quantity_ladder_v1_ref
    description: GAS 하네스 구현 문서화. TP1/TP2/TP3 도달 시 매도할 수량을 GAS에서 자동 산출해 고착화한다. 수동 입력(tp1_qty0
    inputs: {}
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13b_harness_formulas.yaml:TP_QUANTITY_LADDER_V1
    note: GAS-only harness formula.
- formula_id: EVENT_RISK_HOLD_GATE_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: event_risk_hold_gate_v1_ref
    description: GAS 하네스 구현 문서화. 이벤트 홀드 기간(Event_Hold_Days <= 5) 또는 DART 리스크 플래그가
      있는 종목에 신규 매
    inputs: {}
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13b_harness_formulas.yaml:EVENT_RISK_HOLD_GATE_V1
    note: GAS-only harness formula.
- formula_id: VOLUME_BREAKOUT_CONFIRM_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: volume_breakout_confirm_v1_ref
    description: GAS 하네스 구현 문서화. 52주 신고가 97% 이상 부근에서 진입 시 당일 거래량이 5일 평균 거래량×1.2 미만이면
      UNCONFIR
    inputs: {}
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13b_harness_formulas.yaml:VOLUME_BREAKOUT_CONFIRM_V1
    note: GAS-only harness formula.
- formula_id: STOP_PRICE_ADEQUACY_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: stop_price_adequacy_v1_ref
    description: GAS 하네스 구현 문서화. 보유 종목의 수동 손절가가 ATR 기반 권고 손절가 대비 너무 넓게 설정되었는지 검증한다.
      manual_st
    inputs: {}
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13b_harness_formulas.yaml:STOP_PRICE_ADEQUACY_V1
    note: GAS-only harness formula.
- formula_id: HOLDING_STALE_REVIEW_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: holding_stale_review_v1_ref
    description: GAS 하네스 구현 문서화. account_snapshot의 entry_date 기준으로 보유 기간을 산출한다. 60일
      STALE_P
    inputs: {}
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13b_harness_formulas.yaml:HOLDING_STALE_REVIEW_V1
    note: GAS-only harness formula.
- formula_id: TP_TRIGGER_ALERT_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: tp_trigger_alert_v1_ref
    description: GAS 하네스 구현 문서화. 보유 종목 중 close = tp1_price 또는 close = tp2_price인 종목을
      감지한다.
    inputs: {}
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13b_harness_formulas.yaml:TP_TRIGGER_ALERT_V1
    note: GAS-only harness formula.
- formula_id: REGIME_TRANSITION_ALERT_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: regime_transition_alert_v1_ref
    description: GAS 하네스 구현 문서화. 직전 실행 국면(settings.prev_market_regime) vs 현재 marketRegime를
      비교
    inputs: {}
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13b_harness_formulas.yaml:REGIME_TRANSITION_ALERT_V1
    note: GAS-only harness formula.
- formula_id: BUY_TIMING_SUITABILITY_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: buy_timing_suitability_v1_ref
    description: GAS 하네스 구현 문서화. core_satellite 후보 품질과 실제 매수 타이밍을 분리한다.
    inputs: {}
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13b_harness_formulas.yaml:BUY_TIMING_SUITABILITY_V1
    note: GAS-only harness formula.
- formula_id: ANTI_WHIPSAW_HOLD_GATE_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: anti_whipsaw_hold_gate_v1_ref
    description: GAS 하네스 구현 문서화. 연속 매도 신호 5일 이상 + 기관·외국인 순매수 조합을 감지해 가짜 매도(whipsaw)를
      차단한다. WH
    inputs: {}
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13b_harness_formulas.yaml:ANTI_WHIPSAW_HOLD_GATE_V1
    note: GAS-only harness formula.
- formula_id: EXPERT_JUDGMENT_CONSENSUS_ENGINE_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: expert_judgment_consensus_engi_ref
    description: GAS 하네스 구현 문서화. Analyst(기술적 관점)·Trader(실행 타이밍)·Quant(리스크 수치) 3관점
      중 2관점 이상 BL
    inputs: {}
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13b_harness_formulas.yaml:EXPERT_JUDGMENT_CONSENSUS_ENGINE_V1
    note: GAS-only harness formula.
- formula_id: SMART_CASH_RECOVERY_SELL_ENGINE_V2
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: smart_cash_recovery_sell_engin_ref
    description: GAS 하네스 구현 문서화. 현금부족(cashShortfallInfo) 상황에서 value_damage_score 최소화
      조합을 결정론적
    inputs: {}
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13b_harness_formulas.yaml:SMART_CASH_RECOVERY_SELL_ENGINE_V2
    note: GAS-only harness formula.
- formula_id: MACRO_REGIME_ADAPTIVE_GATE_V2
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: macro_regime_adaptive_gate_v2_ref
    description: GAS 하네스 구현 문서화. L1(미시)·L2(거시)·L3(글로벌)·L4(이벤트) 4레이어 각 0~25점 합산 total_mrag_sco
    inputs: {}
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13b_harness_formulas.yaml:MACRO_REGIME_ADAPTIVE_GATE_V2
    note: GAS-only harness formula.
- formula_id: MANDATORY_REDUCTION_PLAN_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: mandatory_reduction_plan_v1_ref
    description: GAS 하네스 구현 문서화. 반도체 클러스터 비중이 cluster_limit * 2.0 초과 시 4주 분할 감축 계획을
      결정론적으로 생성
    inputs: {}
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13b_harness_formulas.yaml:MANDATORY_REDUCTION_PLAN_V1
    note: GAS-only harness formula.
- formula_id: DETERMINISTIC_SERVING_LOCK_ENGINE_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: deterministic_serving_lock_eng_ref
    description: GAS 하네스 구현 문서화. 11개 스테이지 토큰 및 numeric_generation_allowed=0을 통해 LLM이
      가격·수량·수익
    inputs: {}
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13b_harness_formulas.yaml:DETERMINISTIC_SERVING_LOCK_ENGINE_V1
    note: GAS-only harness formula.
- formula_id: VALIDATE_ORDER_CONDITION_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: validate_order_condition_v1_ref
    description: GAS 하네스 구현 문서화. 주문 조건 텍스트에 다중 조건 접속사('또는', '동시 충족', '실패 시' 등)가 포함되면
      INVALID_
    inputs: {}
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13b_harness_formulas.yaml:VALIDATE_ORDER_CONDITION_V1
    note: GAS-only harness formula.
- formula_id: SHADOW_LEDGER_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: shadow_ledger_v1_ref
    description: GAS 하네스 구현 문서화. BLOCKED/INVALID 블루프린트를 HTS 주문표에서 제외하되, 차단 사유 및 산출
      지표를 투명하게 보
    inputs: {}
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13b_harness_formulas.yaml:SHADOW_LEDGER_V1
    note: GAS-only harness formula.
- formula_id: AVG_TRADE_VALUE_SIGNAL_V1
  python_function: GAS_REFERENCE_ONLY
  cases:
  - id: avg_trade_value_signal_v1_ref
    description: GAS 하네스 구현 문서화. secular_leader(005930·000660) PROFIT_LOCK_STAGE_20
      구간에서 5일 평
    inputs: {}
    expected:
      gate: PASS
    tolerance: {}
    provenance: GAS_REFERENCE
    spec_correct_src: spec/13b_harness_formulas.yaml:AVG_TRADE_VALUE_SIGNAL_V1
    note: GAS-only harness formula.
