File size: 23,586 Bytes
1099afe
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
522f7a0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1099afe
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
522f7a0
 
 
 
 
 
 
 
 
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
# DEPENDENCIES
from enum import Enum
from typing import Dict
from typing import List
from typing import Tuple


class ContractType(Enum):
    EMPLOYMENT  = "employment"
    CONSULTING  = "consulting"
    NDA         = "nda"
    SOFTWARE    = "software"
    SERVICE     = "service"
    PARTNERSHIP = "partnership"
    LEASE       = "lease"
    PURCHASE    = "purchase"
    GENERAL     = "general"


class RiskRules:
    """
    Comprehensive risk scoring rules for broad contract coverage
    """
    CATEGORY_WEIGHTS          = {"restrictive_covenants" : 15,
                                 "termination_rights"    : 12,
                                 "penalties_liability"   : 14,
                                 "compensation_benefits" : 13,
                                 "intellectual_property" : 12,
                                 "confidentiality"       : 10,
                                 "liability_indemnity"   : 11,
                                 "governing_law"         : 8,
                                 "payment_terms"         : 10,
                                 "warranties"            : 9,
                                 "dispute_resolution"    : 7,
                                 "assignment_change"     : 6,
                                 "insurance"             : 5,
                                 "force_majeure"         : 4,
                                }
    
    # Contract-specific weight adjustments
    CONTRACT_TYPE_ADJUSTMENTS = {ContractType.EMPLOYMENT  : {"restrictive_covenants": 1.8, "compensation_benefits": 1.6, "termination_rights": 1.4, "confidentiality": 1.3},
                                 ContractType.SOFTWARE    : {"intellectual_property": 1.8, "penalties_liability": 1.5, "warranties": 1.4, "payment_terms": 1.3},
                                 ContractType.NDA         : {"confidentiality": 2.0, "penalties_liability": 1.6, "restrictive_covenants": 1.4},
                                 ContractType.CONSULTING  : {"compensation_benefits": 1.5, "termination_rights": 1.3, "liability_indemnity": 1.4},
                                 ContractType.LEASE       : {"payment_terms": 1.6, "termination_rights": 1.5, "liability_indemnity": 1.4},
                                 ContractType.PURCHASE    : {"warranties": 1.7, "payment_terms": 1.5, "liability_indemnity": 1.3},
                                 ContractType.PARTNERSHIP : {"governing_law": 1.6, "dispute_resolution": 1.5, "assignment_change": 1.4},
                                 ContractType.SERVICE     : {"payment_terms": 1.5, "warranties": 1.4, "termination_rights": 1.3},
                                } 
    
    CRITICAL_KEYWORDS         = {"non-compete"                : 25,
                                 "non-solicit"                : 23,
                                 "non-solicitation"           : 23,
                                 "forfeit"                    : 25,
                                 "liquidated damages"         : 24,
                                 "wage withholding"           : 25,
                                 "unlimited liability"        : 25,
                                 "joint and several"          : 23,
                                 "perpetual"                  : 22,
                                 "irrevocable"                : 20,
                                 "automatic renewal"          : 21,
                                 "assignment without consent" : 22,
                                 "sole discretion"            : 23,
                                }
    
    HIGH_RISK_KEYWORDS        = {"indemnify"             : 18,
                                 "indemnification"       : 18,
                                 "hold harmless"         : 17,
                                 "penalty"               : 18,
                                 "damages"               : 15,
                                 "breach"                : 15,
                                 "default"               : 14,
                                 "immediate termination" : 16,
                                 "without cause"         : 15,
                                 "at-will"               : 14,
                                 "waive"                 : 16,
                                 "release"               : 15,
                                 "confidential"          : 12,
                                 "proprietary"           : 12,
                                 "exclusive"             : 14,
                                 "non-refundable"        : 16,
                                }
    
    MEDIUM_RISK_KEYWORDS      = {"terminate"      : 7, 
                                 "termination"    : 7, 
                                 "assignment"     : 6, 
                                 "warranty"       : 8, 
                                 "representation" : 7, 
                                 "covenant"       : 8, 
                                 "jurisdiction"   : 6, 
                                 "governing law"  : 6, 
                                 "insurance"      : 5, 
                                 "force majeure"  : 4, 
                                 "amendment"      : 5,  
                                 "notice"         : 4,
                                }

    RISKY_PATTERNS            = [(r'\d+\s*(year|yr|month|mo)s?\s*(non-compete|non-solicit)', 20, "Long duration restrictive covenant"),
                                 (r'(entire|all|worldwide|global)\s*(industry|market|territory)', 18, "Overly broad geographic/industry scope"),
                                 (r'notice\s+period.*\d+\s*days.*employee.*\d+\s*days.*employer', 15, "Unequal notice periods"),
                                 (r'(may|can|shall)\s+(withhold|deduct|retain).*compensation', 22, "Wage withholding clause"),
                                 (r'(unlimited|no\s+limit|without\s+limitation).*liability', 25, "Unlimited liability exposure"),
                                 (r'(sole|absolute|unfettered)\s+discretion', 18, "One-sided discretionary power"),
                                 (r'penalty.*(?:equal\s+to|of|amount).*\$?\d+', 16, "Specific penalty amount"),
                                 (r'(automatically|immediately)\s+(renew|extend)', 12, "Auto-renewal clause"),
                                 (r'waive.*right.*arbitration', 20, "Arbitration rights waiver"),
                                 (r'(all|any).*intellectual\s+property.*created', 17, "Broad IP assignment"),
                                 (r'payment.*due.*upon.*signature', 14, "Payment due upon signature"),
                                 (r'no.*warranty.*(?:merchantability|fitness)', 15, "No warranty disclaimer"),
                                 (r'governing\s+law.*\b(?:delaware|nevada)\b', 8, "Specific governing law"),
                                ]

    CLAUSE_RISK_FACTORS       = {"non_compete"           : {"base_risk" : 70,
                                                            "red_flags" : {"same industry": 0, "direct competitor": -5, "entire industry": +20, "all industries": +25, "worldwide": +15, "global": +15, "specific city": -10, "specific state": -5},
                                                           },
                                 "termination"           : {"base_risk" : 50,
                                                            "red_flags" : {"without cause": +15, "immediate": +12, "at will": +10, "sole discretion": +18, "no notice": +20, "no reason": +15},
                                                           },
                                 "indemnification"       : {"base_risk" : 60,
                                                            "red_flags" : {"unlimited": +25, "joint and several": +20, "gross negligence": -10, "willful misconduct": -10, "third party": +8, "all claims": +15, "any claims": +15},
                                                           },
                                 "compensation"          : {"base_risk" : 30,
                                                            "red_flags" : {"to be determined": +20, "tbd": +20, "subject to review": +15, "discretionary": +18, "at employer's discretion": +22, "may withhold": +25, "can deduct": +20},
                                                           },
                                 "intellectual_property" : {"base_risk" : 55,
                                                            "red_flags" : {"all work product": +18, "anything created": +20, "during employment": +10, "after employment": +25, "including personal projects": +30, "whether or not related": +25},
                                                           },
                                 "confidentiality"       : {"base_risk" : 45,
                                                            "red_flags" : {"perpetual": +20, "indefinite": +18, "all information": +15, "including public information": +25},
                                                           },
                                 "payment"               : {"base_risk" : 35,
                                                            "red_flags" : {"net 90": +15, "net 120": +20, "upon completion": +10, "discretionary": +18},
                                                           },
                                 "warranty"              : {"base_risk" : 40,
                                                            "red_flags" : {"as is": +25, "no warranty": +20, "disclaims all": +22},
                                                           },
                                }
    
    INDUSTRY_BENCHMARKS       = {"non_compete_duration"     : {"tech"       : {"reasonable": 6, "standard": 12, "excessive": 24},
                                                               "finance"    : {"reasonable": 12, "standard": 18, "excessive": 36},
                                                               "healthcare" : {"reasonable": 12, "standard": 24, "excessive": 36},
                                                               "general"    : {"reasonable": 6, "standard": 12, "excessive": 24},
                                                              },
                                 "notice_period_days"       : {"executive"    : {"reasonable": 90, "standard": 60, "minimal": 30},
                                                               "senior"       : {"reasonable": 60, "standard": 30, "minimal": 14},
                                                               "professional" : {"reasonable": 30, "standard": 14, "minimal": 7},
                                                               "general"      : {"reasonable": 30, "standard": 14, "minimal": 7},
                                                              },
                                 "liability_cap_multiplier" : {"saas"        : {"generous": 24, "standard": 12, "restrictive": 3},
                                                               "consulting"  : {"generous": 3, "standard": 1, "restrictive": 0.5},
                                                               "general"     : {"generous": 12, "standard": 6, "restrictive": 1},
                                                              },
                                }

    PROTECTION_CHECKLIST      = {"for_cause_definition"     : {"importance": "critical", "risk_if_missing": 25, "categories": ["termination_rights"]},
                                 "severance_provision"      : {"importance": "high", "risk_if_missing": 18, "categories": ["termination_rights", "compensation_benefits"]},
                                 "mutual_indemnification"   : {"importance": "high", "risk_if_missing": 20, "categories": ["liability_indemnity"]},
                                 "liability_cap"            : {"importance": "critical", "risk_if_missing": 25, "categories": ["liability_indemnity", "penalties_liability"]},
                                 "prior_ip_exclusion"       : {"importance": "high", "risk_if_missing": 22, "categories": ["intellectual_property"]},
                                 "confidentiality_duration" : {"importance": "medium", "risk_if_missing": 12, "categories": ["confidentiality"]},
                                 "dispute_resolution"       : {"importance": "medium", "risk_if_missing": 15, "categories": ["dispute_resolution"]},
                                 "change_control_process"   : {"importance": "medium", "risk_if_missing": 10, "categories": ["assignment_change"]},
                                 "insurance_requirements"   : {"importance": "medium", "risk_if_missing": 12, "categories": ["insurance"]},
                                 "force_majeure"            : {"importance": "low", "risk_if_missing": 8, "categories": ["force_majeure"]},
                                }
                        
    RISK_THRESHOLDS           = {"critical" : 80,
                                 "high"     : 60,
                                 "medium"   : 40,
                                 "low"      : 20,
                                }
                            
    CATEGORY_DESCRIPTIONS     = {"restrictive_covenants"  : {"high"   : "Overly restrictive non-compete, non-solicit, or confidentiality terms that may significantly limit future opportunities",
                                                             "medium" : "Some restrictive terms present; review duration, geographic scope, and industry limitations",
                                                             "low"    : "Reasonable restrictive covenants appropriate for this role and industry standards",
                                                            },
                                 "termination_rights"     : {"high"   : "Unbalanced termination rights with immediate termination, 'at-will' clauses, or unequal notice periods favoring one party",
                                                             "medium" : "Moderately balanced termination provisions; review notice period requirements and severance terms",
                                                             "low"    : "Fair termination rights with reasonable notice periods and balanced severance provisions",
                                                            },
                                 "penalties_liability"    : {"high"   : "Excessive penalty clauses, unlimited liability exposure, or one-sided indemnification terms",
                                                             "medium" : "Some concerning liability terms; review indemnification scope, damage limitations, and warranty provisions",
                                                             "low"    : "Standard liability limitations, reasonable penalty provisions, and balanced indemnification terms",
                                                            },
                                 "compensation_benefits"  : {"high"   : "Compensation structure lacks clarity, contains vague terms, or has unfavorable payment conditions",
                                                             "medium" : "Compensation terms are generally clear but could benefit from more specific bonus structure and payment terms",
                                                             "low"    : "Clear and competitive compensation package with well-defined payment terms and bonus structure",
                                                            },
                                 "intellectual_property"  : {"high"   : "Overly broad IP assignment that may cover personal projects or lacks proper prior IP exclusion",
                                                             "medium" : "IP terms mostly clear but could benefit from stronger prior IP protection and clearer ownership terms",
                                                             "low"    : "Well-defined intellectual property ownership, clear usage rights, and proper prior IP exclusion",
                                                            },
                                 "confidentiality"        : {"high"   : "Overly broad confidentiality scope, perpetual duration, or insufficient protection exceptions",
                                                             "medium" : "Standard confidentiality terms with some areas that could be more precisely defined",
                                                             "low"    : "Reasonable confidentiality provisions with appropriate scope and duration",
                                                            },
                                 "liability_indemnity"    : {"high"   : "Unbalanced indemnification, unlimited liability exposure, or insufficient liability caps",
                                                             "medium" : "Moderate liability terms; review indemnification mutuality and liability limitations",
                                                             "low"    : "Balanced indemnification provisions with reasonable liability limitations",
                                                            },
                                 "governing_law"          : {"high"   : "Unfavorable jurisdiction selection, one-sided dispute resolution, or restrictive venue requirements",
                                                             "medium" : "Standard governing law terms with generally acceptable jurisdiction and dispute resolution",
                                                             "low"    : "Reasonable governing law and jurisdiction provisions favorable to both parties",
                                                            },
                                 "payment_terms"          : {"high"   : "Unfavorable payment terms, extended payment periods, or unclear payment conditions",
                                                             "medium" : "Standard payment terms with some areas that could be improved for cash flow",
                                                             "low"    : "Favorable payment terms with reasonable payment periods and clear conditions",
                                                            },
                                 "warranties"             : {"high"   : "Overly broad warranty disclaimers, insufficient product guarantees, or one-sided warranty terms",
                                                             "medium" : "Standard warranty provisions with typical product/service guarantees",
                                                             "low"    : "Comprehensive warranty coverage with reasonable limitations and clear guarantees",
                                                            },
                                 "dispute_resolution"     : {"high"   : "Unfavorable dispute resolution process, restrictive arbitration clauses, or one-sided legal fee allocation",
                                                             "medium" : "Standard dispute resolution terms with generally fair arbitration or litigation process",
                                                             "low"    : "Reasonable dispute resolution process with fair arbitration and cost allocation",
                                                            },
                                 "assignment_change"      : {"high"   : "Restrictive assignment clauses, one-sided change control, or unfavorable amendment procedures",
                                                             "medium" : "Standard assignment and change control terms with reasonable flexibility",
                                                             "low"    : "Reasonable assignment rights and change control processes favorable to both parties",
                                                            },
                                 "insurance"              : {"high"   : "Insufficient insurance requirements, unclear coverage terms, or inadequate policy specifications",
                                                             "medium" : "Standard insurance requirements with typical coverage expectations",
                                                             "low"    : "Comprehensive insurance requirements with clear coverage specifications",
                                                            },
                                 "force_majeure"          : {"high"   : "Overly narrow force majeure definition, insufficient relief provisions, or one-sided termination rights",
                                                             "medium" : "Standard force majeure clause with typical relief provisions",
                                                             "low"    : "Comprehensive force majeure protection with reasonable relief and termination rights",
                                                            },
                                }
        
    PROTECTION_NAME_MAP       = {"for_cause_definition"     : "For Cause Definition",
                                 "severance_proportion"     : "Severance Provision",
                                 "mutual_indemnification"   : "Mutual Indemnification",
                                 "liability_cap"            : "Liability Cap",
                                 "prior_ip_exclusion"       : "Prior IP Exclusion",
                                 "confidentiality_duration" : "Confidentiality Duration Limit",
                                 "dispute_resolution"       : "Dispute Resolution Process",
                                 "change_control_process"   : "Change Control Process",
                                 "insurance_requirements"   : "Insurance Requirements",
                                 "force_majeure"            : "Force Majeure Protection",
                                }

    @classmethod
    def get_adjusted_weights(cls, contract_type: ContractType) -> Dict[str, float]:
        """
        Get category weights adjusted for contract type
        """
        base_weights = cls.CATEGORY_WEIGHTS.copy()
        adjustments  = cls.CONTRACT_TYPE_ADJUSTMENTS.get(contract_type, {})
        
        adjusted    = dict()

        for category, weight in base_weights.items():
            multiplier         = adjustments.get(category, 1.0)
            adjusted[category] = weight * multiplier
        
        # Normalize to sum to 100
        total            = sum(adjusted.values())

        adjusted_weights = {k: (v / total) * 100 for k, v in adjusted.items()}
        
        return adjusted_weights
    

    @classmethod
    def get_category_description(cls, category: str, score: int) -> str:
        """
        Get meaningful description for a category based on score
        """
        if category not in cls.CATEGORY_DESCRIPTIONS:
            return "Review recommended based on risk score"
        
        if (score >= 70):
            risk_level = "high"

        elif (score >= 40):
            risk_level = "medium"

        else:
            risk_level = "low"
        
        category_description = cls.CATEGORY_DESCRIPTIONS[category][risk_level]
        
        return category_description


    @classmethod
    def get_protection_display_name(cls, protection_id: str) -> str:
        """
        Get the display name for a protection ID: Uses PROTECTION_NAME_MAP for known IDs, otherwise formats the ID
        """
        return cls.PROTECTION_NAME_MAP.get(protection_id, protection_id.replace("_", " ").title())