# Helper: Config

**Purpose**: Loads and validates YAML configuration file. Provides typed access to all runtime parameters. Supports dev and production configs.

**Used by**: All 6 components

## Interface

| Method | Input | Output | Error Types |
|--------|-------|--------|-------------|
| `load(path)` | str | Config | ConfigError (missing file, invalid YAML, validation failure) |
| `get(key, default)` | str, Any | Any | KeyError |

## Key Config Sections

```yaml
version: 1
season: winter

tier1:
  backbone: yoloe-11s-seg  # or yoloe-26s-seg
  engine_path: /models/yoloe-11s-seg.engine
  input_resolution: 1280
  confidence_threshold: 0.3

tier2:
  min_branch_length: 20  # pixels, for skeleton pruning
  base_roi_px: 100
  darkness_threshold: 80  # 0-255
  contrast_threshold: 0.3
  freshness_contrast_threshold: 0.2
  cluster_radius_px: 300  # default max distance between cluster members
  min_cluster_size: 2  # default minimum detections to form a cluster

vlm:
  enabled: true
  socket_path: /tmp/vlm.sock
  model: VILA1.5-3B
  timeout_s: 5
  prompt_template: "..."

gimbal:
  mode: real_uart  # or mock_tcp
  port: /dev/ttyTHS1
  baud: 115200
  mock_host: mock-gimbal
  mock_port: 9090
  pid_p: 0.5
  pid_i: 0.01
  pid_d: 0.1

scan:
  sweep_angle_range: 45  # degrees, +/- from center
  sweep_step: 5  # degrees per step
  poi_queue_max: 10
  investigation_timeout_s: 10
  quality_gate_threshold: 50.0  # Laplacian variance

search_scenarios:
  - name: winter_concealment
    enabled: true
    trigger:
      classes: [footpath_winter, branch_pile, dark_entrance]
      min_confidence: 0.5
    investigation:
      type: path_follow
      follow_class: footpath_winter
      target_classes: [concealed_position, branch_pile, dark_entrance, trash]
      use_vlm: true
    priority_boost: 1.0
  - name: building_area_search
    enabled: true
    trigger:
      classes: [building_block, road_with_traces, house_with_vehicle]
      min_confidence: 0.6
    investigation:
      type: area_sweep
      target_classes: [vehicle, military_vehicle, traces, dark_entrance]
      use_vlm: false
    priority_boost: 0.8
  - name: aa_defense_network
    enabled: false
    trigger:
      classes: [radar_dish, aa_launcher, military_truck]
      min_confidence: 0.4
      min_cluster_size: 2
    investigation:
      type: cluster_follow
      target_classes: [radar_dish, aa_launcher, military_truck, command_vehicle]
      cluster_radius_px: 300
      use_vlm: true
    priority_boost: 1.5

output:
  base_dir: /data/output
  recording_l1_fps: 2
  recording_l2_fps: 30
  log_flush_interval: 10  # entries or 5s
  storage_warning_pct: 20

health:
  thermal_vlm_disable_c: 75
  thermal_semantic_disable_c: 80
  gimbal_timeout_s: 4
  vlm_max_failures: 3
  gimbal_max_failures: 3
```

## Validation Rules

- version must be 1
- engine_path must exist on filesystem (warn if not, don't fail — may be building)
- All thresholds must be positive
- gimbal.mode must be "real_uart" or "mock_tcp"
- season must be one of: winter, spring, summer, autumn
- search_scenarios: at least 1 enabled scenario required
- Each scenario must have valid investigation.type: "path_follow", "area_sweep", "zoom_classify", or "cluster_follow"
- path_follow scenarios must specify follow_class
- cluster_follow scenarios must specify min_cluster_size (>= 2) and cluster_radius_px (> 0)
- trigger.classes must be non-empty list of strings
