feat: add verdict/evidence verification model
This commit is contained in:
@@ -40,26 +40,60 @@ class ReviewEntry:
|
||||
@dataclass
|
||||
class Correctness:
|
||||
"""Verfolgt die Korrektheit eines Engramms über Zeit."""
|
||||
# verdict model (not only binary confirm/reject)
|
||||
# Values:
|
||||
# - unknown
|
||||
# - probable_true / probable_false
|
||||
# - confirmed_true / confirmed_false
|
||||
verdict: str = "unknown"
|
||||
evidence: List[Dict[str, Any]] = field(default_factory=list)
|
||||
confirmed: bool = False
|
||||
confirmations: int = 0
|
||||
rejections: int = 0
|
||||
last_reviewed: Optional[str] = None
|
||||
review_history: List[ReviewEntry] = field(default_factory=list)
|
||||
|
||||
def is_final(self) -> bool:
|
||||
return self.verdict in ("confirmed_true", "confirmed_false")
|
||||
|
||||
def set_verdict(self, by: str, verdict: str, note: str = "", evidence: Optional[List[Dict[str, Any]]] = None) -> None:
|
||||
verdict = (verdict or "").strip()
|
||||
if verdict not in ("unknown", "probable_true", "probable_false", "confirmed_true", "confirmed_false"):
|
||||
verdict = "unknown"
|
||||
self.verdict = verdict
|
||||
# Keep backward-compatible boolean in sync:
|
||||
# historically, confirmed=True meant "this statement is correct".
|
||||
self.confirmed = verdict == "confirmed_true"
|
||||
self.last_reviewed = _now()
|
||||
if evidence:
|
||||
try:
|
||||
self.evidence.extend([e for e in evidence if isinstance(e, dict)])
|
||||
except Exception:
|
||||
pass
|
||||
self.review_history.append(ReviewEntry(by, "set_verdict", self.last_reviewed, f"{verdict}: {note}".strip()))
|
||||
|
||||
def confirm(self, by: str, note: str = "") -> None:
|
||||
self.confirmations += 1
|
||||
self.confirmed = True
|
||||
self.last_reviewed = _now()
|
||||
self.set_verdict(by, "confirmed_true", note)
|
||||
# Preserve historic action tag too
|
||||
self.review_history.append(ReviewEntry(by, "confirm", self.last_reviewed, note))
|
||||
|
||||
def reject(self, by: str, note: str = "") -> None:
|
||||
self.rejections += 1
|
||||
self.confirmed = False
|
||||
self.last_reviewed = _now()
|
||||
self.set_verdict(by, "confirmed_false", note)
|
||||
self.review_history.append(ReviewEntry(by, "reject", self.last_reviewed, note))
|
||||
|
||||
def score(self) -> float:
|
||||
"""Confidence-Score aus Korrekturhistorie."""
|
||||
# verdict-first scoring (explicit, non-binary)
|
||||
if self.verdict == "confirmed_true":
|
||||
return 1.0
|
||||
if self.verdict == "confirmed_false":
|
||||
return 0.0
|
||||
if self.verdict == "probable_true":
|
||||
return 0.75
|
||||
if self.verdict == "probable_false":
|
||||
return 0.25
|
||||
total = self.confirmations + self.rejections
|
||||
if total == 0:
|
||||
return 0.5 # Unbestimmt
|
||||
@@ -74,6 +108,8 @@ class Correctness:
|
||||
else:
|
||||
review_history.append(entry.to_dict())
|
||||
return {
|
||||
"verdict": self.verdict,
|
||||
"evidence": self.evidence,
|
||||
"confirmed": self.confirmed,
|
||||
"confirmations": self.confirmations,
|
||||
"rejections": self.rejections,
|
||||
@@ -84,11 +120,30 @@ class Correctness:
|
||||
@classmethod
|
||||
def from_dict(cls, d: dict) -> "Correctness":
|
||||
c = cls()
|
||||
verdict = d.get("verdict")
|
||||
if isinstance(verdict, str) and verdict.strip():
|
||||
c.verdict = verdict.strip()
|
||||
c.confirmed = d.get("confirmed", False)
|
||||
c.confirmations = d.get("confirmations", 0)
|
||||
c.rejections = d.get("rejections", 0)
|
||||
c.last_reviewed = d.get("last_reviewed")
|
||||
ev = d.get("evidence", [])
|
||||
if isinstance(ev, list):
|
||||
c.evidence = [e for e in ev if isinstance(e, dict)]
|
||||
c.review_history = [ReviewEntry.from_dict(r) for r in d.get("review_history", [])]
|
||||
# Backfill verdict if missing/invalid.
|
||||
if c.verdict not in ("unknown", "probable_true", "probable_false", "confirmed_true", "confirmed_false"):
|
||||
if c.confirmed:
|
||||
c.verdict = "confirmed_true"
|
||||
elif c.rejections > 0:
|
||||
c.verdict = "confirmed_false"
|
||||
else:
|
||||
c.verdict = "unknown"
|
||||
# Ensure boolean stays consistent for older mixed data.
|
||||
if c.verdict == "confirmed_true":
|
||||
c.confirmed = True
|
||||
elif c.verdict == "confirmed_false":
|
||||
c.confirmed = False
|
||||
return c
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user