schema_version: 1
case_id: expensive-query-spike-during-incident-window
ground_truth:
  root_cause: A read-heavy query path lacked an efficient access path, forcing a large scan and concentrating read pressure on a small set of TiKV nodes
judge:
  semantic_strategy: undecided
  contract:
    checks:
    - id: time_window_match
      required: true
      description: Actual diagnosis time window matches one allowed case window.
      match: all_of
      rules:
      - source: trace_fact
        matcher: bool_true
        path: time_window_match
    - id: cluster_scope_match
      required: true
      description: Actual diagnosis cluster scope matches expected cluster id.
      match: all_of
      rules:
      - source: trace_fact
        matcher: bool_true
        path: cluster_scope_match
  workflow:
    checks:
    - id: architecture_context_loaded
      weight: 5
      required: true
      description: Architecture context is loaded.
      match: all_of
      rules:
      - source: workflow_fact
        matcher: bool_true
        path: architecture_context_loaded
    - id: misdiagnosis_guardrails_loaded
      weight: 5
      required: true
      description: Misdiagnosis guardrails are loaded.
      match: all_of
      rules:
      - source: workflow_fact
        matcher: bool_true
        path: misdiagnosis_guardrails_loaded
    - id: diagnosis_run_initialized
      weight: 5
      required: true
      description: Diagnosis run is initialized.
      match: all_of
      rules:
      - source: workflow_fact
        matcher: bool_true
        path: diagnosis_run_initialized
    - id: evidence_collection_completed
      weight: 10
      required: true
      description: Evidence collection completes.
      match: all_of
      rules:
      - source: workflow_fact
        matcher: bool_true
        path: evidence_collection_completed
    - id: summary_read_completed
      weight: 5
      required: false
      description: Summary artifact is read when available.
      match: all_of
      rules:
      - source: workflow_fact
        matcher: bool_true
        path: summary_read_completed
    - id: final_answer_emitted
      weight: 0
      required: false
      description: Final answer is emitted.
      match: all_of
      rules:
      - source: workflow_fact
        matcher: bool_true
        path: final_answer_emitted
  execution_contract:
    checks:
    - id: required_workflow_present
      required: true
      description: Required workflow milestones are present.
      match: all_of
      rules:
      - source: workflow_check
        matcher: subset_observed
        paths:
        - architecture_context_loaded
        - misdiagnosis_guardrails_loaded
        - diagnosis_run_initialized
        - evidence_collection_completed
    - id: required_artifacts_present
      required: true
      description: Required evidence artifacts are present.
      match: all_of
      rules:
      - source: artifact_fact
        matcher: subset_observed
        paths:
        - core_evidence_bundle_present
    - id: preferred_channels_minimum_observed
      required: true
      description: At least one preferred evidence channel is observed.
      match: all_of
      rules:
      - source: channel_fact
        matcher: count_gte
        paths:
        - logs
        - query_or_metric
        threshold: 1
    - id: preferred_channels_all_observed
      required: false
      description: Preferred evidence channels are all observed.
      match: all_of
      rules:
      - source: channel_fact
        matcher: subset_observed
        paths:
        - logs
        - query_or_metric
  evidence_collection:
    weight: 5
    checks:
    - id: required_artifacts_present
      weight: 4
      required: true
      description: Required evidence artifacts are present and readable.
      match: all_of
      rules:
      - source: artifact_fact
        matcher: subset_observed
        paths:
        - core_evidence_bundle_present
    - id: preferred_channels_minimum_observed
      weight: 0
      required: true
      description: At least the minimum number of preferred evidence channels are observed.
      match: all_of
      rules:
      - source: channel_fact
        matcher: count_gte
        paths:
        - logs
        - query_or_metric
        threshold: 1
    - id: preferred_channels_all_observed
      weight: 6
      required: false
      description: Preferred evidence channels are all observed.
      match: all_of
      rules:
      - source: channel_fact
        matcher: subset_observed
        paths:
        - logs
        - query_or_metric
  critical_evidence:
    weight: 30
    checks:
    - id: expensive_query_log_signal_present
      weight: 8
      description: Evidence uses TiDB expensive-query or slow-query logs as a primary source.
      match: any_of
      rules:
      - source: artifact_json
        artifacts:
        - queries
        matcher: json_text_contains_any
        keywords:
        - slow_query
        - expensive query
        - query_time
        - sql_preview
      - source: logs
        matcher: keyword_any
        keywords:
        - slow_query
        - expensive query
        - query_time
    - id: plan_bottleneck_signal_present
      weight: 8
      description: Evidence shows a large-scan or ineffective access-path bottleneck for the dominant query.
      match: any_of
      rules:
      - source: artifact_json
        artifacts:
        - queries
        matcher: json_text_contains_any
        keywords:
        - IndexFullScan
        - FullScan
        - actRows
        - estRows
        - process_keys
      - source: artifact_json
        artifacts:
        - summary_json
        matcher: json_text_contains_any
        keywords:
        - full scan
        - large scan
        - wrong index
        - ineffective index
    - id: hotspot_impact_signal_present
      weight: 9
      description: Evidence shows the expensive-query path concentrated read pressure on a small set of TiKV nodes.
      match: any_of
      rules:
      - source: artifact_json
        artifacts:
        - metrics
        matcher: json_text_contains_any
        keywords:
        - TiKV CPU
        - grpc
        - hotspot
        - IOPS
        - db-tikv
      - source: artifact_json
        artifacts:
        - summary_json
        matcher: json_text_contains_any
        keywords:
        - read hotspot
        - hot nodes
        - throttling
        - read pressure
  evidence_routing:
    weight: 5
    checks:
    - id: analysis_patch_valid_json
      weight: 1
      required: true
      description: Analysis patch is valid JSON whenever the patch exists.
      match: any_of
      rules:
      - source: routing_fact
        matcher: bool_false
        path: analysis_patch_present
      - source: routing_fact
        matcher: bool_true
        path: analysis_patch_valid_json
    - id: analysis_items_shape_valid
      weight: 2
      required: true
      description: Analysis patch items are structurally valid whenever the patch exists.
      match: any_of
      rules:
      - source: routing_fact
        matcher: bool_false
        path: analysis_patch_present
      - source: routing_fact
        matcher: bool_true
        path: analysis_items_shape_valid
    - id: analysis_key_evidence_present
      weight: 2
      required: true
      description: Analysis patch includes key evidence whenever the patch exists.
      match: any_of
      rules:
      - source: routing_fact
        matcher: bool_false
        path: analysis_patch_present
      - source: routing_fact
        matcher: bool_true
        path: analysis_has_key_evidence
    - id: metric_refs_resolvable
      weight: 1
      required: true
      description: Metric references resolve whenever the patch requires them.
      match: any_of
      rules:
      - source: routing_fact
        matcher: bool_false
        path: analysis_metric_refs_required
      - source: routing_fact
        matcher: bool_true
        path: analysis_metric_refs_resolvable
    - id: query_refs_resolvable
      weight: 1
      required: true
      description: Query references resolve whenever the patch requires them.
      match: any_of
      rules:
      - source: routing_fact
        matcher: bool_false
        path: analysis_query_refs_required
      - source: routing_fact
        matcher: bool_true
        path: analysis_query_refs_resolvable
    - id: supporting_evidence_present
      weight: 0
      required: false
      description: Analysis patch includes supporting evidence whenever the patch exists.
      match: any_of
      rules:
      - source: routing_fact
        matcher: bool_false
        path: analysis_patch_present
      - source: routing_fact
        matcher: bool_true
        path: analysis_has_supporting_evidence
    - id: analysis_log_or_event_channel_resolvable
      weight: 0
      required: false
      description: Routed log or event items stay resolvable against observed channels.
      match: all_of
      rules:
      - source: routing_fact
        matcher: bool_true
        path: analysis_log_or_event_channel_resolvable
  diagnosis:
    checks:
    - id: mention_expensive_query_log_evidence
      mode: blended
      weight: 3
      required: false
      description: References TiDB expensive-query or slow-query log evidence for the dominant query path.
      deterministic:
        match: any_of
        rules:
        - source: output_text
          matcher: keyword_any
          keywords:
          - slow query log
          - expensive query log
          - TiDB log
          - slow_query
          - TiDB 慢日志
      semantic:
        id: 1
        title: 日志证据引用
        description: |
          判断回答是否引用 TiDB expensive-query 或 slow-query log 作为相关证据，
          不要求固定分析顺序。
    - id: identify_large_scan_or_missing_access_path
      mode: blended
      weight: 3
      required: true
      description: Identifies an ineffective access path such as large scan or missing index as the main query bottleneck.
      deterministic:
        match: any_of
        rules:
        - source: output_text
          matcher: keyword_any
          keywords:
          - IndexFullScan
          - full scan
          - missing index
          - ineffective index
          - large scan
          - 全表扫描
          - 缺少索引
      semantic:
        id: 2
        title: 起点与机制判断
        description: |
          判断回答是否从 TiDB expensive-query 或 slow-query evidence 出发，
          并说明 large scan 或 ineffective access path 才是主机制。
    - id: reject_analyze_as_primary_culprit
      mode: deterministic_only
      scoring_mode: penalty
      weight: 3
      required: false
      description: Does not elevate ANALYZE-related queries into the primary culprit.
      deterministic:
        match: all_of
        rules:
        - source: output_fact
          matcher: bool_false
          path: analyze_primary_culprit_asserted
    - id: recommend_index_or_access_path_fix
      mode: blended
      weight: 3
      required: false
      description: Recommends fixing the access path first.
      deterministic:
        match: any_of
        rules:
        - source: output_text
          matcher: keyword_any
          keywords:
          - add index
          - composite index
          - access path
          - SQL binding
          - 增加索引
          - 访问路径
      semantic:
        id: 4
        title: 修复建议对齐
        description: |
          判断回答是否优先建议 index 或 access-path fix，
          并把 statistics refresh 放在 follow-up 或 secondary remediation。
