Simulated legal review
This rubric is a demonstration of analytics mechanics, not legal advice. It encodes a
plausible but simplified set of review criteria and must be labeled as simulated
everywhere it appears.
Inputs
Clause categories used
A subset of CUAD's actual 41 categories carries the contract-risk story. Weights are stored as data, not hard-coded.
Corrected against the real dataset
CUAD v1 has no "Indemnification" or "Limitation of Liability" category. Liability
exposure is expressed as
Uncapped Liability / Cap On Liability.
The rubric below uses CUAD's real category names (see findings).| CUAD clause category | Risk theme | Weight |
|---|---|---|
| Uncapped Liability | Uncapped exposure present | High |
| Cap On Liability (absent) | No cap on liability | High |
| Termination For Convenience | Counterparty may exit at will | Medium |
| Anti-Assignment | Assignment restricted | Medium |
| Change Of Control | Ownership-change trigger | Medium |
| Minimum Commitment | Minimum purchase/volume | Medium |
| Governing Law (absent) | No forum specified | Medium |
| Non-Compete / Exclusivity | Restrictive scope | Low |
| Renewal Term / Notice Period | Auto-renewal notice windows | Low |
Rubric
Rule-based scoring
Each rule evaluates an annotation (presence, absence, or a keyword signal) and contributes points. Scores roll up per contract and per matter.
CREATE TABLE core.ref_risk_rule (
rule_id STRING,
clause_category STRING,
signal STRING, -- PRESENT | ABSENT | KEYWORD
pattern STRING,
points INT,
rationale STRING
);
-- Examples
-- ('R1','Limitation of liability','ABSENT', NULL, 40,'No cap on liability')
-- ('R2','Indemnification','PRESENT', NULL, 25,'Indemnity present; review scope')
-- ('R3','Governing law','KEYWORD','foreign|arbitration', 10,'Offshore forum')
Risk bands: High ≥ 60 Medium 30–59 Low < 30.
Outputs
Analytics views
CREATE OR REPLACE VIEW marts.mart_matter_risk AS
SELECT m.matter_id, m.matter_name, c.contract_id, c.contract_type,
SUM(CASE WHEN r.signal='ABSENT' AND f.answer='No' THEN r.points
WHEN r.signal='PRESENT' AND f.answer='Yes' THEN r.points
WHEN r.signal='KEYWORD' AND f.clause_text ILIKE '%'||r.pattern||'%'
THEN r.points ELSE 0 END) AS risk_score
FROM core.dim_matter m
JOIN core.bridge_matter_contract b USING (matter_id)
JOIN core.dim_contract c USING (contract_id)
JOIN core.fact_clause f ON f.contract_id = c.contract_id
JOIN core.ref_risk_rule r ON r.clause_category = f.clause_category
GROUP BY 1,2,3,4;
Because dim_matter and fact_clause carry
matter_id, the same row access policy scopes these analytics — an
attorney's risk report only covers their authorized matters.
Full SQL: sql/04_risk_views.sql.
Illustration
Illustrative output
| Matter | Contract type | Score | Band | Driving clauses |
|---|---|---|---|---|
| SYN-1042 | Service Agreement | 72 | High | No liability cap; broad indemnity |
| SYN-1088 | License Agreement | 45 | Medium | Auto-renewal; assignment consent |
| SYN-1103 | NDA | 18 | Low | Residuals clause |
Values are illustrative; the demo generates them from the loaded contracts.