rules:

  # ── Trailing / Exit Rules ────────────────────────────────────────────────────

  - id: KB001
    trigger:
      analyzer: reversal
      condition: "reversal_rate > 0.15"
    action_label: "Enable trailing stop to protect in-profit trades (reversal rate high)"
    mutations:
      InpUseTrailing:
        set: true
      InpTrailStartPips:
        derive_from: "mfe_p25"    # 25th percentile of reversal MFE
        fallback: 20.0
      InpTrailStepPips:
        set: 10.0
    strategy: targeted

  - id: KB002
    trigger:
      analyzer: reversal
      condition: "reversal_rate > 0.20"
    action_label: "Tighten TP ratio — too many trades reversing before target hit"
    mutations:
      InpRRRatio:
        multiply: 0.80
        clamp_min: 1.0
    strategy: targeted

  - id: KB003
    trigger:
      analyzer: reversal
      condition: "mean_capture_ratio < 0.55"
    action_label: "Low MFE capture on winners — enable or tighten trailing"
    mutations:
      InpUseTrailing:
        set: true
      InpTrailStartPips:
        set: 15.0
      InpTrailStepPips:
        set: 8.0
    strategy: targeted

  # ── Session / Time Filter Rules ───────────────────────────────────────────────

  - id: KB004
    trigger:
      analyzer: time_performance
      condition: "type == 'hour_window'"
    action_label: "Exclude identified negative-edge UTC time window via session filter"
    mutations:
      InpUseSession:
        set: true
      InpSessionEnd:
        derive_from: "broker_start"   # end session before bad window starts
    strategy: targeted

  - id: KB005
    trigger:
      analyzer: time_performance
      condition: "type == 'session'"
    action_label: "Negative-edge session detected — tighten or disable session window"
    mutations:
      InpUseSession:
        set: true
    strategy: targeted

  # ── Entry Quality Rules ────────────────────────────────────────────────────────

  - id: KB006
    trigger:
      analyzer: entry_exit_quality
      condition: "diagnosis == 'poor_entry'"
    action_label: "Poor entry quality — tighten ATR filter and score gate"
    mutations:
      InpUseSpreadGuard:
        set: true
      InpMinScore:
        multiply: 1.125
        clamp_min: 6
      InpATRMultiplier:
        multiply: 1.20
        clamp_min: 0.3
    strategy: targeted

  - id: KB007
    trigger:
      analyzer: entry_exit_quality
      condition: "diagnosis == 'good_entry_poor_exit'"
    action_label: "Good entries, poor exits — enable trailing with conservative start"
    mutations:
      InpUseTrailing:
        set: true
      InpTrailStartPips:
        set: 18.0
      InpTrailStepPips:
        set: 10.0
    strategy: targeted

  - id: KB008
    trigger:
      analyzer: entry_exit_quality
      condition: "diagnosis == 'both_broken'"
    action_label: "Both entry and exit quality poor — test conservative bot mode"
    mutations:
      InpBotMode:
        set: 2
      InpMinScore:
        multiply: 1.25
        clamp_min: 6
    strategy: compound

  # ── Risk / Drawdown Rules ─────────────────────────────────────────────────────

  - id: KB009
    trigger:
      analyzer: equity_curve
      condition: "flatness_score > 0.50"
    action_label: "Equity spending too much time in drawdown — reduce risk per trade"
    mutations:
      InpRiskPercent:
        multiply: 0.75
        clamp_min: 0.5
      InpMaxDailyLossPct:
        multiply: 0.80
        clamp_min: 1.0
    strategy: targeted

  - id: KB010
    trigger:
      analyzer: equity_curve
      condition: "cluster_count > 3"
    action_label: "Repeated loss clusters — limit consecutive trades and daily risk"
    mutations:
      InpMaxTradesPerDay:
        multiply: 0.75
        clamp_min: 2
      InpMaxDailyLossPct:
        set: 2.0
    strategy: targeted

  # ── Breakeven Rules ────────────────────────────────────────────────────────────

  - id: KB011
    trigger:
      analyzer: reversal
      condition: "reversal_rate > 0.12"
    action_label: "Enable breakeven stop to lock in partial profit before reversal"
    mutations:
      InpUseBreakeven:
        set: true
      InpBEPips:
        derive_from: "mfe_p25"
        fallback: 15.0
      InpBEBufferPips:
        set: 2.0
    strategy: targeted

  # ── Filter Tightening Rules ────────────────────────────────────────────────────

  - id: KB012
    trigger:
      analyzer: entry_exit_quality
      condition: "high_mae_loser_count > 10"
    action_label: "High MAE losers — require EMA slope confirmation"
    mutations:
      InpUseEMA:
        set: true
      InpRequireEMASlope:
        set: true
      InpEMASlopeBars:
        set: 2
    strategy: targeted

  - id: KB013
    trigger:
      analyzer: entry_exit_quality
      condition: "mean_entry_quality < 0.35"
    action_label: "Very poor entry quality — tighten minimum RR gate"
    mutations:
      InpUseMinRR:
        set: true
      InpMinRRRatio:
        multiply: 1.25
        clamp_min: 1.0
    strategy: targeted
