Spaces:
Sleeping
Sleeping
File size: 1,629 Bytes
d04144c | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | from __future__ import annotations
from dataclasses import dataclass
from .integration import IntegratedRoleResult
from .schemas import SharedRolePacket
@dataclass(frozen=True)
class CompletionCheck:
passed: bool
resolution_score: float
violations: tuple[str, ...]
missing_evidence_task_ids: tuple[str, ...]
class CompletionGate:
def evaluate(self, packet: SharedRolePacket, integrated: IntegratedRoleResult, *, external_violations=()) -> CompletionCheck:
violations = list(external_violations)
by_task = {item.task_id: item for item in integrated.resolutions}
missing_evidence: list[str] = []
resolved = 0
for task in packet.tasks:
resolution = by_task.get(task.task_id)
if resolution is None or not resolution.resolved:
violations.append("major_need_missing"); continue
if task.required_facts and not resolution.evidence_ids:
missing_evidence.append(task.task_id); violations.append("evidence_incomplete"); continue
if task.actionability_required and not resolution.action_steps:
violations.append("required_actionability_missing"); continue
resolved += 1
if integrated.missing_task_ids: violations.append("major_need_missing")
if integrated.contradiction_task_ids: violations.append("contradiction")
total = max(1, len(packet.tasks))
deduped = tuple(dict.fromkeys(violations))
return CompletionCheck(not deduped and resolved == len(packet.tasks), resolved / total, deduped, tuple(sorted(set(missing_evidence))))
|