types.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 """Shared types for the freeze reviewer engine."""
2
3 from __future__ import annotations
4
5 from dataclasses import dataclass, field
6 from typing import Literal
7
8 Severity = Literal["BLOCKER", "MAJOR", "MINOR"]
9 Category = Literal[
10 "security",
11 "irreversible",
12 "real_money",
13 "gates_tier3",
14 "completeness",
15 "consistency",
16 "other",
17 ]
18 Verdict = Literal["pass", "findings", "blocked"]
19 EscalationReason = Literal["mode_human", "provider_unreachable"]
20 DeclarationStatus = Literal["present", "absent"]
21 ArtifactKind = Literal[
22 "markdown_fence",
23 "yaml_whole",
24 "operator_forced_md",
25 "operator_forced_yaml",
26 ]
27
28
29 @dataclass(frozen=True)
30 class ChecklistItem:
31 """One checklist entry (built-in §K5.5 or operator file)."""
32
33 id: str
34 title: str
35 typical_severity: Severity
36
37
38 @dataclass
39 class Finding:
40 """A cited freeze-review finding (§K5.6)."""
41
42 id: str = ""
43 check: str = ""
44 severity: Severity = "MINOR"
45 category: Category = "other"
46 path: str = ""
47 line: int = 1
48 message: str = ""
49 citation: str = ""
50
51 def with_citation(self) -> Finding:
52 """Ensure citation matches path:line."""
53 self.citation = f"{self.path}:{self.line}"
54 return self
55
56 def is_valid_citation(self) -> bool:
57 return bool(self.path) and self.line >= 1 and self.citation == f"{self.path}:{self.line}"
58
59
60 @dataclass(frozen=True)
61 class ReviewerSettings:
62 """Effective reviewer configuration for one invocation."""
63
64 mode: str
65 model: str | None
66 provider: str | None
67 fallback: str | None
68
69
70 @dataclass
71 class ReviewStamp:
72 """Machine review stamp written on pass (§K5.7)."""
73
74 reviewed_at: str
75 verdict: Verdict
76 reviewer_mode: str
77 reviewer_model: str | None
78 reviewer_provider: str | None
79 kit_version: str
80 artifact_digest: str
81
82 def to_mapping(self) -> dict:
83 return {
84 "reviewed_at": self.reviewed_at,
85 "verdict": self.verdict,
86 "reviewer_mode": self.reviewer_mode,
87 "reviewer_model": self.reviewer_model,
88 "reviewer_provider": self.reviewer_provider,
89 "kit_version": self.kit_version,
90 "artifact_digest": self.artifact_digest,
91 }
92
93
94 @dataclass
95 class ReviewResult:
96 """Internal review outcome before CLI exit mapping."""
97
98 verdict: Verdict = "pass"
99 findings: list[Finding] = field(default_factory=list)
100 escalation: str | None = None
101 reason: EscalationReason | None = None
102 provider_cause: str | None = None
103 stamp: ReviewStamp | None = None
104 stamp_written: bool = False
105 declaration: DeclarationStatus = "absent"
106 artifact_kind: ArtifactKind = "operator_forced_md"
107 dry_run: bool = False
108 no_stamp: bool = False
109 config_error: str | None = None
110 refused: bool = False
111 refuse_cause: str | None = None
112 io_error: bool = False
113 checklist_ids: list[str] = field(default_factory=list)