schema_version: 1
case_id: periodic-tidb-cpu-spike-during-incident-window
ground_truth:
  root_cause: TiDB GC on db-tidb-0 was triggered by memory pressure, with non-prepared statement plan cache growth keeping memory above the GC trigger threshold.
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:
        - 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:
        - 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:
        - 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:
        - query_or_metric
  critical_evidence:
    weight: 30
    checks:
    - id: gc_signal_present
      weight: 8
      description: Evidence shows abnormal TiDB GC pressure or GC trigger activity for the incident window.
      match: any_of
      rules:
      - source: artifact_json
        artifacts:
        - metrics
        - workspace_report
        - summary_json
        matcher: json_text_contains_any
        keywords:
        - GC
        - gc
        - gc pressure
        - server_memory_limit_gc_trigger
        - pause
    - id: heap_profile_signal_present
      weight: 8
      description: Evidence includes heap-profile or memory-retention signals pointing to the memory driver.
      match: any_of
      rules:
      - source: artifact_json
        artifacts:
        - workspace_report
        - summary_json
        matcher: json_text_contains_any
        keywords:
        - heap profile
        - heap
        - plan cache
        - inuse_space
        - memory retention
        - dominant allocation
        - non-prepared
    - id: single_instance_scope_signal_present
      weight: 7
      description: Evidence isolates the issue to db-tidb-0.
      match: any_of
      rules:
      - source: artifact_json
        artifacts:
        - metrics
        - workspace_report
        - summary_json
        matcher: json_text_contains_any
        keywords:
        - db-tidb-0
        - single TiDB
        - one TiDB instance
  diagnosis:
    checks:
    - id: identify_gc_pressure_as_primary_driver
      mode: blended
      weight: 4
      required: true
      description: Identifies TiDB GC pressure as the primary driver of the periodic CPU spikes.
      deterministic:
        match: any_of
        rules:
        - source: output_text
          matcher: keyword_any
          keywords:
          - TiDB GC
          - GC
          - GC pressure
          - memory pressure
          - 内存压力
          - GC 触发
      semantic:
        id: 1
        title: 主路径判断
        description: |
          判断回答是否把周期性 CPU spike 的主路径识别为 TiDB GC 压力，
          而不是停在 generic CPU 或 application-side spike。
    - id: identify_heap_profile_dominant_stack
      mode: blended
      weight: 4
      required: true
      description: Uses heap-profile or memory-retention evidence to explain the memory driver.
      deterministic:
        match: any_of
        rules:
        - source: output_text
          matcher: keyword_any
          keywords:
          - heap profile
          - heap
          - plan cache
          - memory retention
          - dominant allocation
      semantic:
        id: 2
        title: 堆内存证据
        description: |
          判断回答是否使用 heap profile 或 memory-retention 证据把内存驱动说清楚，
          而不是把它停留在泛化的 memory growth 结论上。
    - id: single_node_scope_evidence_present
      mode: blended
      weight: 3
      required: true
      description: Explicitly states the issue is scoped to db-tidb-0.
      deterministic:
        match: any_of
        rules:
        - source: output_text
          matcher: keyword_any
          keywords:
          - db-tidb-0
          - single TiDB
          - single node
          - 单个 TiDB
          - 单节点
      semantic:
        id: 3
        title: 范围识别
        description: |
          判断回答是否明确把问题范围锁定到 db-tidb-0，而不是 cluster-wide。
    - id: reject_application_or_tiproxy_as_primary_root_cause
      mode: blended
      scoring_mode: penalty
      weight: 3
      required: false
      description: Avoids elevating application-side issue or TiProxy load balancing into the primary root cause.
      deterministic:
        match: any_of
        rules:
        - source: output_text
          matcher: regex_any
          patterns:
          - "(application-side|app side|业务侧).{0,60}(root cause|主因|根因)"
          - "(tiproxy|load balancing|负载均衡).{0,60}(root cause|主因|根因)"
          - "(root cause|主因|根因).{0,60}(application-side|app side|业务侧|tiproxy|load balancing|负载均衡)"
      semantic:
        id: 4
        title: 误诊排除
        description: |
          判断回答是否把 application-side issue 或 TiProxy load balancing 错误地抬升为最终根因。
    - id: recommend_gc_followup
      mode: blended
      weight: 2
      required: false
      description: Recommends follow-up centered on GC or memory evidence.
      deterministic:
        match: any_of
        rules:
        - source: output_text
          matcher: keyword_any
          keywords:
          - GC
          - heap profile
          - go gc
          - 内存
      semantic:
        id: 5
        title: 后续动作对齐
        description: |
          判断建议是否围绕 GC 或内存证据继续排查，而不是发散到无关方向。
