schema_version: 1
case_id: ticdc-dataflow-stall-during-incident-window
ground_truth:
  root_cause: TiCDC was stalled after puller because the Kafka sink path was repeatedly failing with EOF, broken-pipe, and TLS close-notify errors against the downstream Kafka proxy, so checkpoint lag kept growing while upstream activity remained present.
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: false
      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:
        - misdiagnosis_guardrails_loaded
        - diagnosis_run_initialized
        - evidence_collection_completed
    - id: required_artifacts_present
      required: true
      description: Required diagnosis report artifact is present.
      match: all_of
      rules:
      - source: artifact_fact
        matcher: subset_observed
        paths:
        - diagnosis_report_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 diagnosis report artifact is present and readable.
      match: all_of
      rules:
      - source: artifact_fact
        matcher: subset_observed
        paths:
        - diagnosis_report_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: primary_symptom_evidence_present
      weight: 8
      description: Direct TiCDC downstream-stall evidence is present within the incident window.
      match: all_of
      rules:
      - source: logs
        matcher: keyword_any
        keywords:
        - "schedulerv3: slow table"
      - source: logs
        matcher: keyword_any
        keywords:
        - "checkpointLag="
      - source: logs
        matcher: keyword_any
        keywords:
        - "changefeed=changefeed-2046429488116162560"
    - id: root_cause_mechanism_evidence_present
      weight: 10
      description: Direct Kafka sink connectivity failure evidence is present within the incident window.
      match: all_of
      rules:
      - source: logs
        matcher: keyword_any
        keywords:
        - "client/metadata got error from broker"
        - "Closed connection to broker"
      - source: logs
        matcher: keyword_any
        keywords:
        - "kafka-sink-proxy"
        - "write: broken pipe"
        - "failed to send closeNotify alert"
    - id: changefeed_context_evidence_present
      weight: 6
      required: false
      description: Evidence includes TiCDC changefeed-specific log context rather than only generic infrastructure logs.
      match: any_of
      rules:
      - source: logs
        matcher: keyword_any
        keywords:
        - "changefeed=changefeed-2046429488116162560"
        - "ticdc-1379661944646414117-ticdc-"
  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 are resolvable whenever the patch contains metric refs.
      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 are resolvable whenever the patch contains query refs.
      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: identify_downstream_pipeline_stall_after_puller
      mode: blended
      weight: 3
      required: true
      description: Identifies the primary problem as a downstream TiCDC pipeline stall after puller rather than a source-side no-data condition.
      deterministic:
        match: any_of
        rules:
        - source: output_text
          matcher: keyword_any
          keywords:
          - after puller
          - post-puller
          - downstream blocked
          - downstream pipeline
          - downstream stages
          - sorter -> mounter -> sink
          - sink 完全阻塞
          - puller 正常工作
          - "puller: ok"
          - "upstream tikv → [puller"
          - upstream data flows
          - lock resolver events confirm
          - puller still has data
          - puller still advancing
          - puller is not the bottleneck
          - 下游阶段
          - 下游处理链路
          - 后续阶段
          - puller 还有数据
          - puller 仍在推进
          - 不是 puller 问题
          - 不是 puller 本身
          - 不是puller本身
      semantic:
        id: 1
        title: 主路径判断
        description: |
          判断回答是否识别主问题发生在 puller 之后的下游处理阶段，
          而不是把现象误判成 source side 没数据或 puller 本身故障。
    - id: identify_kafka_sink_connectivity_primary_mechanism
      mode: blended
      weight: 3
      required: true
      description: Identifies Kafka sink connectivity or proxy-side connection failure as the primary blocking mechanism.
      deterministic:
        match: any_of
        rules:
        - source: output_text
          matcher: keyword_any
          keywords:
          - Kafka Sink
          - kafka sink
          - kafka proxy
          - broker connectivity
          - metadata got error from broker
          - broken pipe
          - closeNotify
          - EOF
          - sarama
          - sink 完全阻塞
          - Kafka 代理
          - Kafka 连接
          - broker 连通性
      semantic:
        id: 2
        title: 机制定位
        description: |
          判断回答是否把主机制收敛到 Kafka sink 侧的连接失败、broker/proxy 异常、
          EOF / broken pipe / TLS 相关错误，而不是停留在泛泛的“CDC 慢”。
    - id: reject_puller_or_source_side_primary_root_cause
      mode: deterministic_only
      scoring_mode: penalty
      weight: 3
      required: false
      description: Does not misdiagnose the incident as a puller-side or source-side primary root cause.
      deterministic:
        match: all_of
        rules:
        - source: output_fact
          matcher: bool_false
          path: puller_or_source_side_primary_root_cause_asserted
    - id: use_checkpoint_or_dispatcher_lag_as_supporting_evidence
      mode: blended
      weight: 3
      required: false
      description: Uses checkpoint lag or frozen checkpoint progression as supporting evidence for the downstream stall.
      deterministic:
        match: any_of
        rules:
        - source: output_text
          matcher: keyword_any
          keywords:
          - owner_ckp_lag
          - checkpoint_ts
          - checkpoint lag
          - checkpointTs
          - checkpoint not advancing
          - lag growing at
          - 1.000s/s
          - 线性增长
          - checkpoint 延迟
          - checkpoint 没有推进
          - checkpoint 没推进
      semantic:
        id: 3
        title: 佐证使用
        description: |
          判断回答是否把 checkpoint lag 持续增长、checkpoint_ts 冻结或类似的
          时序信号当作支持性证据，用来证明问题确实卡在 puller 之后的处理链路。
    - id: recommend_kafka_sink_connectivity_followup
      mode: blended
      weight: 3
      required: false
      description: Recommends follow-up actions aligned with Kafka sink connectivity, proxy, broker, or TLS investigation.
      deterministic:
        match: any_of
        rules:
        - source: output_text
          matcher: keyword_any
          keywords:
          - inspect kafka proxy
          - check broker connectivity
          - check TLS
          - check certificate
          - check kafka broker logs
          - 排查 Kafka 代理
          - 排查 broker 连通性
          - 检查 TLS
          - 检查证书
          - 检查 Kafka broker 日志
      semantic:
        id: 4
        title: 修复建议对齐
        description: |
          判断回答是否把后续动作对齐到 Kafka sink / proxy / broker / TLS 侧排查，
          而不是只给笼统的扩容建议。
