| """03: Contract completeness — A/B level, universal best practice. |
| |
| Universal contract-completeness checks (not jurisdiction-specific): |
| * termination terms (high) — required for predictability |
| * governing law (medium) — required for dispute resolution |
| * penalty for high-value contracts (>1M) — uses a parity threshold |
| * confidentiality clause (low) — only flagged when explicitly False |
| """ |
|
|
| from __future__ import annotations |
|
|
| from domain_checks.base import is_empty, make_risk |
| from graph.states.pipeline_state import Risk |
| from utils.numbers import coerce_number |
|
|
|
|
| _REGULATION = "Universal contract completeness" |
|
|
| _CONTRACT_CRITICAL_FIELDS = [ |
| ("termination_terms", "Termination terms", "high", |
| "Without termination terms, the contract carries unpredictable risk."), |
| ("governing_law", "Governing law", "medium", |
| "Missing governing law creates uncertainty in any dispute."), |
| ] |
|
|
|
|
| class ContractCompletenessCheck: |
| check_id = "check_03_contract_completeness" |
| regulation = _REGULATION |
| is_hu_specific = False |
| applies_to = {"contract"} |
|
|
| def apply(self, extracted: dict) -> list[Risk]: |
| risks: list[Risk] = [] |
|
|
| |
| for field, label, sev, explanation in _CONTRACT_CRITICAL_FIELDS: |
| if is_empty(extracted.get(field)): |
| risks.append(make_risk( |
| description=f"Missing contract element: {label}", |
| severity=sev, |
| rationale=explanation, |
| regulation=_REGULATION, |
| source_check_id=self.check_id, |
| )) |
|
|
| |
| |
| |
| value_dict = extracted.get("value") or {} |
| if isinstance(value_dict, dict) and value_dict: |
| total = coerce_number(value_dict.get("amount")) |
| currency = value_dict.get("currency", "") |
| else: |
| total = coerce_number(extracted.get("total_value")) |
| currency = extracted.get("currency", "") |
|
|
| if is_empty(extracted.get("penalty")) and total is not None and total > 1_000_000: |
| risks.append(make_risk( |
| description="No penalty clause defined in a high-value contract", |
| severity="medium", |
| rationale=( |
| f"Contract value is {total:,.0f} {currency} but no penalty " |
| f"clause is present. For high-value contracts, a penalty " |
| f"clause is best practice for predictable enforcement." |
| ), |
| regulation="Universal contract proportionality", |
| source_check_id=self.check_id, |
| )) |
|
|
| |
| |
| if extracted.get("confidentiality_clause") is False: |
| risks.append(make_risk( |
| description="Confidentiality clause missing", |
| severity="low", |
| rationale=( |
| "The contract has no confidentiality clause. In B2B " |
| "relationships, protecting business information is recommended." |
| ), |
| regulation=_REGULATION, |
| source_check_id=self.check_id, |
| )) |
|
|
| return risks |
|
|