types.py python
170 lines 4.6 KB
Raw
sha256:8461d44b77376fbf06fa7c3e085d309e3010fd8d5886d63c63e69ce118811ad4 docs: record AFF-b feature-tip SHAs after AFF-b-ISR commit. Human 5 days ago
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 # §FRV.3.2 / §FRV.5.1 — CLI-owned stamp keys (fourteen) plus legacy verdict.
29 CLI_OWNED_STAMP_KEYS = frozenset(
30 {
31 "gate",
32 "reviewed_at",
33 "mechanical_verdict",
34 "produced_by",
35 "provider_kind",
36 "reviewer_mode",
37 "reviewer_model",
38 "reviewer_provider",
39 "checklist_ids",
40 "checklist_source",
41 "findings_count",
42 "override_applied",
43 "kit_version",
44 "artifact_digest",
45 "verdict", # legacy — dropped on write
46 }
47 )
48
49 STAMP_KEY_ORDER = (
50 "gate",
51 "reviewed_at",
52 "mechanical_verdict",
53 "produced_by",
54 "provider_kind",
55 "reviewer_mode",
56 "reviewer_model",
57 "reviewer_provider",
58 "checklist_ids",
59 "checklist_source",
60 "findings_count",
61 "override_applied",
62 "kit_version",
63 "artifact_digest",
64 )
65
66
67 @dataclass(frozen=True)
68 class ChecklistItem:
69 """One checklist entry (built-in §K5.5 or operator file)."""
70
71 id: str
72 title: str
73 typical_severity: Severity
74
75
76 @dataclass
77 class Finding:
78 """A cited freeze-review finding (§K5.6)."""
79
80 id: str = ""
81 check: str = ""
82 severity: Severity = "MINOR"
83 category: Category = "other"
84 path: str = ""
85 line: int = 1
86 message: str = ""
87 citation: str = ""
88
89 def with_citation(self) -> Finding:
90 """Ensure citation matches path:line."""
91 self.citation = f"{self.path}:{self.line}"
92 return self
93
94 def is_valid_citation(self) -> bool:
95 return bool(self.path) and self.line >= 1 and self.citation == f"{self.path}:{self.line}"
96
97
98 @dataclass(frozen=True)
99 class ReviewerSettings:
100 """Effective reviewer configuration for one invocation."""
101
102 mode: str
103 model: str | None
104 provider: str | None
105 fallback: str | None
106
107
108 @dataclass
109 class ReviewStamp:
110 """Mechanical review stamp written on pass (§K5.7 / §FRV.3–§FRV.4)."""
111
112 reviewed_at: str
113 mechanical_verdict: Verdict
114 reviewer_mode: str
115 reviewer_model: str | None
116 reviewer_provider: str | None
117 kit_version: str
118 artifact_digest: str
119 gate: str = "mechanical"
120 produced_by: str = "checklist_engine"
121 provider_kind: str = "rule_engine"
122 checklist_ids: list[str] = field(default_factory=list)
123 checklist_source: str = "builtin"
124 findings_count: int = 0
125 override_applied: bool = False
126
127 def to_mapping(self) -> dict:
128 """Emit exactly the fourteen §FRV.3.2 keys in frozen order; never verdict."""
129 return {
130 "gate": self.gate,
131 "reviewed_at": self.reviewed_at,
132 "mechanical_verdict": self.mechanical_verdict,
133 "produced_by": self.produced_by,
134 "provider_kind": self.provider_kind,
135 "reviewer_mode": self.reviewer_mode,
136 "reviewer_model": self.reviewer_model,
137 "reviewer_provider": self.reviewer_provider,
138 "checklist_ids": list(self.checklist_ids),
139 "checklist_source": self.checklist_source,
140 "findings_count": self.findings_count,
141 "override_applied": self.override_applied,
142 "kit_version": self.kit_version,
143 "artifact_digest": self.artifact_digest,
144 }
145
146
147 @dataclass
148 class ReviewResult:
149 """Internal review outcome before CLI exit mapping."""
150
151 verdict: Verdict = "pass"
152 findings: list[Finding] = field(default_factory=list)
153 escalation: str | None = None
154 reason: EscalationReason | None = None
155 provider_cause: str | None = None
156 stamp: ReviewStamp | None = None
157 stamp_written: bool = False
158 declaration: DeclarationStatus = "absent"
159 artifact_kind: ArtifactKind = "operator_forced_md"
160 dry_run: bool = False
161 no_stamp: bool = False
162 config_error: str | None = None
163 refused: bool = False
164 refuse_cause: str | None = None
165 io_error: bool = False
166 checklist_ids: list[str] = field(default_factory=list)
167 escalation_refused: bool = False
168 escalation_refuse_cause: str | None = None
169 operator_block: bool | None = None
170 existing_stamp_verdict: str | None = None
File History 1 commit
sha256:8461d44b77376fbf06fa7c3e085d309e3010fd8d5886d63c63e69ce118811ad4 docs: record AFF-b feature-tip SHAs after AFF-b-ISR commit. Human 5 days ago