# anu.codex_high_classification_rules.v1
# task-2611 Track B — Codex HIGH/HOLD 를 두 계열로 분류하는 라우팅 룰.
#
# 회장 verbatim §2: "Codex HIGH 를 security/scope/credential 계열과
#   coverage/test/claim mismatch 계열로 분류. Critical7 이면 CHAIR_HOLD,
#   아니면 AUTO_REMEDIATION_HOLD 후보."
#
# 분류 우선순위 (deterministic, 약화 금지):
#   1) shared invariant 파손        -> CHAIR_HOLD (Critical7 동급, 회장 §6)
#   2) Critical7 매치 (critical7_rules.yaml) -> CHAIR_HOLD
#   3) 그 외 HIGH/HOLD              -> AUTO_REMEDIATION_HOLD 후보
#      (coverage / test_failure / claim_mismatch / 기타 non-critical)
#
# Critical7 게이트가 1순위 독립 평가이므로, 미매치 HIGH 를
# AUTO_REMEDIATION 으로 수렴시키는 것은 Critical7 약화가 아니다(회장 §3 자동수렴).

schema: anu.codex_high_classification_rules.v1
version: "1.0.0"
authority: >-
  회장 결정 2026-05-19 — task-2611 Track B. classifier 출력은 Track A
  batch_hold_adjudicator(task-2610) 입력이 된다.
critical7_ruleset: config/critical7_rules.yaml
preflight_ref: memory/events/task-2610-batch-hold-system-preflight-decision_260519.json

severity_in_scope: [HIGH, CRITICAL]

routes:
  CHAIR_HOLD:
    description: Critical7 또는 shared invariant 파손. 회장 보고. 자동 수렴 금지.
    triggered_by: [invariant_break, critical7]
  AUTO_REMEDIATION_HOLD:
    description: non-Critical HOLD. 회장 §3 자동 수렴 대상 (Track C planner 입력).
    triggered_by: [remediation_family, high_unmatched]

# Critical7 family alias — critical7_rules.yaml 의 family 와 1:1.
critical7_families: [security, credential, permission, forbidden_path, scope_expansion, merge_write, owner_pat]

# non-Critical 계열 신호 (회장 verbatim: coverage / test / claim mismatch 계열).
remediation_families:
  coverage:
    keywords:
      - coverage
      - uncovered
      - branch coverage
      - line coverage
      - untested code
      - coverage drop
      - coverage regression
      - below threshold
  test_failure:
    keywords:
      - test fail
      - failing test
      - test failure
      - assertion error
      - assertionerror
      - regression fail
      - pytest fail
      - broke test
      - broken test
      - red test
      - flaky test
      - mock-only
      - mock only
  claim_mismatch:
    keywords:
      - claim mismatch
      - claimed but
      - does not match claim
      - mismatch between
      - unverified claim
      - overclaim
      - over-claim
      - doc-only
      - doc only
      - documentation only
      - no real entrypoint
      - evidence mismatch
      - result does not match
  lint:
    keywords: [lint, flake8, ruff, style violation, formatting, pep8]

# Critical7 미매치 + remediation_families 미매치인 HIGH/HOLD 의 기본 라우트.
# 회장 §3: non-Critical HOLD 자동 수렴. Critical7 게이트는 이미 1순위로
# 독립 평가되었으므로 이 fallback 은 Critical7 약화가 아니다.
default_when_high_unmatched:
  route: AUTO_REMEDIATION_HOLD
  family: high_unmatched
  rationale: >-
    Critical7 게이트(우선순위2)에서 이미 탈락한 HIGH. 회장 §3 "non-Critical
    HOLD 는 AUTO_REMEDIATION_HOLD 로 자동 수렴". Critical7 기준 약화 아님.

# classifier 출력 계약 (Track A batch_hold_adjudicator 입력).
output_contract:
  schema: anu.codex_high_classification.v1
  per_finding_fields: [finding_id, severity, family, route, critical7, matched_terms, reasons]
  batch_fields: [batch_verdict, any_critical7, any_invariant_break, critical7_rules_hit, remediation_candidates, chair_hold_findings]
  batch_verdict_rule: >-
    any_invariant_break OR any_critical7 -> CHAIR_HOLD;
    elif any HIGH/HOLD -> AUTO_REMEDIATION_HOLD;
    else GO.
  consumer: anu_v3/batch_hold_adjudicator.py (task-2610 Track A)
