version: 6
status: adaptive-23-28-cross-shot-blur
scope:
  technical_families:
    - black
    - flicker
    - freeze
    - judder
    - lipsync
    - deformation
    - blur
  excluded_until_separate_module:
    - identity_continuity
    - hand_finger_count
    - clothing_accessories_continuity
    - prop_continuity
    - liquid_presence
    - spatial_continuity

detector:
  analysis_fps: 12
  strong_signal_policy: preserve_in_secondary_review_queue
  protection_rules:
    black:
      detector_prefixes: [black]
    freeze:
      detector_prefixes: [freeze]
    flicker:
      score_min: 50.0
      local_second_difference_min: 45.0
    judder:
      score_min: 9.0
      stall_fraction_min: 0.10
    deformation:
      anchor_score_min: 9.0
      strain_z_min: 3.0
      residual_z_min: 5.0
    blur:
      score_min: 8.0
      sharpness_ratio_max: 0.20
      consecutive_frames_min: 5
      camera_motion_max: 4.0
    lipsync:
      priorities: [high]
      source_verdicts: [FROZEN_OPEN_MOUTH]
  black:
    min_duration_s: 0.10
    classify_transitions: true
  freeze:
    min_duration_s: 0.65
    exact_duplicate_diff: 0.12
  flicker:
    high_density_frames: 24
    consecutive_anomaly_frames: 2
  judder:
    max_candidate_width_s: 2.0
    classify_shot_endpoints: true
  lipsync:
    require_visible_face: true
    require_audio_attribution: true
    phoneme_matching: false
  deformation:
    high_density_frames: 24
    consecutive_anomaly_frames: 2
    use_dynamic_face_roi: true
    use_shot_anchor_roi: true
    require_camera_motion_context: true
    preserve_peak_windows: true
  blur:
    status: calibration
    min_shot_duration_s: 0.8
    consecutive_anomaly_frames: 5
    bridge_normal_frames: 1
    global_ratio_max: 0.42
    moving_global_ratio_max: 0.28
    face_ratio_max: 0.42
    face_local_body_ratio_min: 0.62
    high_camera_motion: 4.0
    shot_context:
      enabled: true
      neighbor_radius: 3
      reference_percentile: 75.0
      min_neighbor_shots: 2
      min_shot_duration_s: 0.5
      global_ratio_max: 0.75
      face_ratio_max: 0.75

evidence_windows:
  enabled: true
  default_duration_s: 1.0
  clip_to_technical_shot: true
  exact_grid_window: true
  detailed_face_rois: true
  stable_face_tracking: true
  families:
    deformation:
      duration_s: 0.96
      clip_to_technical_shot: true
    flicker:
      duration_s: 0.96
      clip_to_technical_shot: true
    blur:
      duration_s: 1.20
      clip_to_technical_shot: true
    judder:
      duration_s: 1.50
      clip_to_technical_shot: true
    black:
      duration_s: 1.50
      clip_to_technical_shot: true
    freeze:
      duration_s: 1.50
      clip_to_technical_shot: true

perceptual_filter:
  enabled: true
  min_duration_s: 0.20
  min_source_frames: 5
  min_vlm_abnormal_frames: 5
  min_vlm_abnormal_frames_by_family:
    flicker: 2
    deformation: 2
    blur: 5
  preserve_raw_candidates: true
  filter_before_paid_vlm: true
  families:
    black:
      min_duration_s: 0.12
      min_source_frames: 3
    freeze:
      min_duration_s: 0.65
      min_source_frames: 17
    flicker:
      duration_evidence_key: anomaly_duration_s
      min_duration_s: 0.08
      min_source_frames: 2
    judder:
      mode: vlm
      min_duration_s: 0.20
      min_source_frames: 5
    deformation:
      mode: vlm
      min_duration_s: 0.20
      min_source_frames: 5
    blur:
      duration_evidence_key: duration_s
      min_duration_s: 0.20
      min_source_frames: 5
    lipsync:
      min_duration_s: 0.20
      min_source_frames: 5

vlm:
  provider_primary: doubao
  concurrency: 50
  provider_secondary: []
  skip_families:
    - lipsync
  context_filter:
    enabled: true
    allow_viewer_queue_downgrade: true
    preserve_raw_candidate: true
    preserve_protected_signal: true
    min_confidence: 0.85
    normal_contexts:
      - normal-transition
      - normal-fast-motion
      - normal-effect
      - normal-expression
      - normal-cut
      - normal-depth-of-field
      - normal-motion-blur
      - normal-hold
      - minor-motion-variation
    blur_drop_rescue:
      enabled: true
      contexts:
        - style-softness
        - normal-depth-of-field
      score_min: 8.0
      sharpness_ratio_max: 0.38
      consecutive_frames_min: 5
      camera_motion_max: 4.0
  deformation_input: source-frame-spaced-full-face-eyes-hair-mouth-grid
  deformation_specialists:
    enabled: true
    merge_policy: any-yes-keep-any-unknown-uncertain
    tasks:
      - face
      - eyes-hair
      - mouth-chin
  blur_input: source-frame-spaced-full-plus-roi-grid-with-sharpness-evidence
  flicker_input: source-frame-spaced-full-grid
  lipsync_input: detector_only
  black_freeze_input: shot_clipped_context_clip
  judder_input: shot_clipped_context_clip
  keep_on:
    - keep
    - uncertain
  never_drop_raw:
    - TECH_STRONG
    - exact_black
    - exact_freeze
    - strong_judder
    - strong_lipsync_static
    - strong_deformation
    - strong_blur

output:
  include_raw_clip: true
  include_24_frame_grid: true
  include_detector_evidence: true
  include_vlm_json: true
  include_review_state: true
  include_viewer_review_state: true
  include_review_window: true
  compact:
    enabled: true
    screenshot_format: jpg
    draw_face_boxes: true
    include_lipsync: false
    prune_intermediate: false

performance:
  feature_extraction:
    mode: fast-feature-v1
    max_width: 960
    face_detect_interval: 3
    face_hold_frames: 2
    motion_max_width: 640
    motion_max_corners: 200
    reuse_small_for_frame_lap: true
    fast_math: true
  detector:
    parallel_stages:
      enabled: true
      max_workers: 3
  media:
    concurrency: 4

review_queue:
  strategy: temporal-stratified-risk
  total_budget: 28
  lipsync_budget: 12
  visual_budget: 28
  family_minimums:
    blur: 18
  allocation:
    mode: fixed-reserve
    lipsync:
      max_items: 12
      selection_strategy: temporal-stratified
    visual:
      family_minimums:
        blur: 18
        deformation: 3
      family_maximums: {}
      family_order:
        - blur
        - deformation
      selection_strategy: temporal-stratified
  adaptive:
    enabled: true
    master_budget: 28
    min_items: 23
    max_items: 28
    risk_threshold: 0.64
  merge_gap_s: 0.18
  lipsync_merge_gap_s: 0.25
  reviewable_candidates_only: true
  event_interval: t
  recall_at_k:
    - 20
    - 30
    - 40
    - 50
    - 60
  scoring:
    detector_family_percentile_weight: 0.48
    vlm_decision_weight: 0.30
    protected_signal_bonus: 0.22
    normal_context_penalty: -0.18
    deformation_normal_expression_penalty: 0.0
  policy:
    preserve_raw_candidates: true
    lipsync_separate_from_visual_budget: true
    unknown_is_reviewable: true
    normal_expression_is_not_hard_drop_for_deformation: true
