narcolepticchicken's picture
Upload playbook.py
cad7c8b verified
"""
Playbook rules, fallback positions, and risk flags for contract drafting.
Hard-coded expert knowledge — not model memory.
"""
from typing import List, Dict, Optional
# ---------------------------------------------------------------------------
# Contract-type → required clauses mapping
# ---------------------------------------------------------------------------
CONTRACT_REQUIRED_CLAUSES: Dict[str, List[str]] = {
"saas_agreement": [
"scope_of_services", "subscription_term", "fees_and_payment",
"data_protection", "limitation_of_liability", "indemnification",
"intellectual_property", "termination", "service_level_agreement",
"confidentiality", "governing_law", "assignment",
],
"msa": [
"scope_of_work", "fees_and_payment", "term_and_termination",
"intellectual_property", "confidentiality", "limitation_of_liability",
"indemnification", "warranty", "insurance", "governing_law",
"dispute_resolution", "assignment", "subcontracting",
],
"nda": [
"definition_of_confidential_information", "obligations_of_receiving_party",
"permitted_disclosures", "term", "return_of_information",
"remedies", "governing_law", "no_license",
],
"sow": [
"scope_of_services", "deliverables", "timeline_and_milestones",
"fees_and_payment", "acceptance_criteria", "change_order",
"intellectual_property", "confidentiality", "limitation_of_liability",
"indemnification", "governing_law", "termination",
],
"dpa": [
"definitions_and_roles", "data_processing", "subprocessors",
"data_subject_rights", "security_measures", "audit_rights",
"data_transfer", "breach_notification", "liability",
"term_and_termination", "governing_law", "confidentiality",
],
"vendor_agreement": [
"scope_of_goods", "purchase_orders", "pricing_and_payment",
"delivery_and_inspection", "warranty", "limitation_of_liability",
"indemnification", "intellectual_property", "confidentiality",
"termination", "governing_law", "assignment",
],
"consulting_agreement": [
"scope_of_services", "fees_and_expenses", "term_and_termination",
"intellectual_property", "confidentiality", "non_solicitation",
"limitation_of_liability", "indemnification", "independent_contractor",
"governing_law", "dispute_resolution", "assignment",
],
"ip_assignment": [
"assignment_of_rights", "moral_rights", "warranty_of_title",
"consideration", "future_works", "confidentiality",
"representation_and_warranty", "indemnification", "governing_law",
"further_assurances", "recordation", "survival",
],
"employment_agreement": [
"position_and_duties", "compensation", "benefits",
"term_and_termination", "confidentiality", "intellectual_property",
"non_compete", "non_solicitation", "dispute_resolution",
"governing_law", "assignment", "at_will_employment",
],
}
# ---------------------------------------------------------------------------
# Fallback positions when playbook lacks explicit rules
# ---------------------------------------------------------------------------
FALLBACK_POSITIONS: Dict[str, Dict[str, str]] = {
"limitation_of_liability": {
"pro_company": "Consequential damages excluded; cap at annual fees.",
"balanced": "Consequential damages excluded; cap at fees paid.",
"pro_counterparty": "No exclusion of consequential damages; cap at 12-month fees.",
},
"indemnification": {
"pro_company": "Mutual indemnification; narrow scope for company.",
"balanced": "Mutual indemnification for IP and data breach.",
"pro_counterparty": "Broad company indemnification; carve-outs for counterparty.",
},
"termination": {
"pro_company": "Company may terminate for convenience with 30 days notice.",
"balanced": "Either party may terminate for convenience with 60 days notice.",
"pro_counterparty": "Termination for convenience requires 90 days notice; auto-renewal.",
},
"intellectual_property": {
"pro_company": "Company retains all IP; grant of limited license to counterparty.",
"balanced": "Each party retains pre-existing IP; new IP assigned per SOW.",
"pro_counterparty": "Counterparty retains IP; broad license back to company.",
},
"confidentiality": {
"pro_company": "Broad definition; 3-year survival; standard exceptions.",
"balanced": "Standard definition; 3-year survival; standard exceptions.",
"pro_counterparty": "Narrow definition; 5-year survival; broad exceptions.",
},
"governing_law": {
"pro_company": "Delaware law; company-friendly venue.",
"balanced": "Delaware law; neutral venue.",
"pro_counterparty": "Counterparty's state law; counterparty-friendly venue.",
},
"data_protection": {
"pro_company": "Standard security; no DPA required under threshold.",
"balanced": "Standard security; DPA required for regulated data.",
"pro_counterparty": "Enhanced security; mandatory DPA; audit rights.",
},
"warranty": {
"pro_company": "AS IS; limited warranty; disclaimer of implied warranties.",
"balanced": "Limited warranty; disclaimer of consequential warranties.",
"pro_counterparty": "Robust warranty; retention of all implied warranties.",
},
"non_compete": {
"pro_company": "Broad non-compete; 12-month; wide geographic scope.",
"balanced": "Limited non-compete; 6-month; narrow scope.",
"pro_counterparty": "No non-compete; or 3-month with narrow scope.",
},
}
def get_required_clauses(contract_type: str) -> List[str]:
"""Return required clauses for a contract type."""
return CONTRACT_REQUIRED_CLAUSES.get(contract_type, [])
def get_fallback_position(clause_name: str, party_position: str) -> Optional[str]:
"""Return fallback language for a clause when no template matches."""
fb = FALLBACK_POSITIONS.get(clause_name, {})
return fb.get(party_position)
def list_contract_types() -> List[str]:
return list(CONTRACT_REQUIRED_CLAUSES.keys())
def list_clauses_for(contract_type: str) -> List[str]:
return CONTRACT_REQUIRED_CLAUSES.get(contract_type, [])