checklist.py file-level

at main · View file ↗ · Intel ↗

History
1 files
1 commits
0 hotspots
0 🧊 dead
0 💥 blast risk
sha256:6 fix(ISR): default require_independent_second_reviewer to require Opera… · aaronrene · Sep 2, 2026
1 """Built-in freeze reviewer checklist (§K5.5)."""
2
3 from __future__ import annotations
4
5 from pathlib import Path
6
7 import yaml
8
9 from adapters.errors import ConfigError
10 from tools.freeze_reviewer.types import ChecklistItem, Severity
11
12 BUILTIN_CHECKLIST: tuple[ChecklistItem, ...] = (
13 ChecklistItem("C1", "Ground-truth edge", "MAJOR"),
14 ChecklistItem("C2", "Completeness", "BLOCKER"),
15 ChecklistItem("C3", "Internal consistency", "MAJOR"),
16 ChecklistItem("C4", "Security", "BLOCKER"),
17 ChecklistItem("C5", "Irreversibility", "BLOCKER"),
18 ChecklistItem("C6", "Real money", "BLOCKER"),
19 ChecklistItem("C7", "Tier-3 linkage", "BLOCKER"),
20 ChecklistItem("C8", "Citation readiness", "MINOR"),
21 )
22
23 VALID_SEVERITIES = frozenset({"BLOCKER", "MAJOR", "MINOR"})
24
25
26 def builtin_checklist() -> list[ChecklistItem]:
27 """Return a copy of the §K5.5 built-in checklist."""
28 return list(BUILTIN_CHECKLIST)
29
30
31 def load_checklist_file(path: Path) -> list[ChecklistItem]:
32 """Parse and validate an operator ``--checklist`` file."""
33 try:
34 raw = yaml.safe_load(path.read_text(encoding="utf-8"))
35 except yaml.YAMLError as exc:
36 raise ConfigError(f"invalid checklist YAML: {exc}", str(path)) from exc
37 if not isinstance(raw, dict):
38 raise ConfigError("checklist root must be a mapping", str(path))
39 checks = raw.get("checks")
40 if not isinstance(checks, list) or not checks:
41 raise ConfigError("checklist checks must be a non-empty list", str(path))
42 items: list[ChecklistItem] = []
43 for index, entry in enumerate(checks):
44 if not isinstance(entry, dict):
45 raise ConfigError(f"checks[{index}] must be a mapping", str(path))
46 check_id = entry.get("id")
47 title = entry.get("title")
48 severity = entry.get("typical_severity")
49 if not isinstance(check_id, str) or not check_id.strip():
50 raise ConfigError(f"checks[{index}].id must be a non-empty string", str(path))
51 if not isinstance(title, str) or not title.strip():
52 raise ConfigError(f"checks[{index}].title must be a non-empty string", str(path))
53 if severity not in VALID_SEVERITIES:
54 raise ConfigError(
55 f"checks[{index}].typical_severity must be BLOCKER|MAJOR|MINOR",
56 str(path),
57 )
58 items.append(ChecklistItem(check_id, title, severity)) # type: ignore[arg-type]
59 return items