Domain Specific Language for Unlawful Detainer Laws - jurisgpt/GrizlyUDVacator GitHub Wiki

California Unlawful Detainer Laws - Domain Specific Language : Key Rules & Automation Guide

This document summarizes California eviction laws, focusing on statutory deadlines, court procedures, and Domain-Specific Language (DSL) rules for modeling timelines in code.This DSL can be used to generate Python classes, Answer Set Programming (ASP) logic, or Z3 constraints for formal verification of eviction timelines. Recommendations for implementation are included.


Key Changes from AB 2347 (Effective Jan 1, 2025)

Change Code Section Deadline Type Impact
Tenant Response Time CCP § 1167 10 court days Doubled from 5 days; more defense prep
Motion Hearings AB 2347 7 court days Faster hearings for demurrers/motions
Discovery Cutoff CCP § 2024.040 5 court days Discovery ends 5 court days pre-trial

Court Days vs. Calendar Days

Court Days

Exclude weekends, Sundays, and judicial holidays. Used for:

  1. Tenant responses to UD complaints (CCP § 1167).
  2. Hearings on motions/demurrers (AB 2347).
  3. Discovery deadlines (CCP § 2024.040(b)(1)).

Calendar Days

Include all days (extend deadlines if they fall on non-court days). Used for:

  1. Landlord notices (3-day pay-or-quit, CCP § 1161).
  2. Termination notices (30/60 days, Civ. Code §§ 1946, 1946.1).
  3. Post-foreclosure evictions (CCP § 1161a).

DSL Rules for Automation

Model deadlines and procedures programmatically.

1. Time Calculations

from datetime import datetime, timedelta
from holidays import US

class CaliforniaHolidays(US):
    def _populate(self, year):
        super()._populate(year)
        # Add CA-specific judicial holidays here

def add_court_days(start_date: datetime, days: int) -> datetime:
    current = start_date
    added_days = 0
    while added_days < days:
        current += timedelta(days=1)
        if current.weekday() < 5 and current not in CaliforniaHolidays():
            added_days += 1
    return current

2. Tenant Response Deadline (AB 2347)

def tenant_response_deadline(served_date: datetime) -> datetime:
    return add_court_days(served_date, 10)

3. Landlord Notices (Calendar Days)

def three_day_notice_deadline(served_date: datetime) -> datetime:
    # Extends deadline if it falls on a non-court day
    deadline = served_date + timedelta(days=3)
    while deadline.weekday() >= 5 or deadline in CaliforniaHolidays():
        deadline += timedelta(days=1)
    return deadline

4. Notices and Responses

# Three-day notices (calendar days).
rule("CCP_1161_Notice") {
    notice_type: ["PayRent", "CureCovenant", "QuitWithoutCure"],
    deadline: deadline(start_date=Date.served, duration=3, unit=TimeUnit.CALENDAR_DAYS),
    action: "Landlord must wait 3 calendar days before filing UD."
}

# Tenant response to UD complaint (court days).
rule("AB2347_Response") {
    trigger: "UD_Complaint_Filed",
    deadline: deadline(start_date=Date.served, duration=10, unit=TimeUnit.COURT_DAYS),
    action: "Tenant must respond within 10 court days."
}

5. Motions and Hearings

# Demurrer/motion hearings (court days).
rule("AB2347_Hearing") {
    trigger: "Demurrer_Filed",
    deadline: deadline(start_date=Date.filed, duration=7, unit=TimeUnit.COURT_DAYS),
    requirement: "Hearing must occur within 7 court days unless extended for good cause."
}

# Discovery cutoff (court days).
rule("Discovery_Cutoff") {
    trigger: "Trial_Date_Set",
    deadline: deadline(start_date=Date.trial, duration=-5, unit=TimeUnit.COURT_DAYS),
    action: "Discovery ends 5 court days before trial."
}

6. Termination Notices (Calendar Days)

python
rule("CivilCode_1946_Termination") {
    notice_type: ["MonthToMonth"],
    duration: lambda tenancy_years: 60 if tenancy_years >= 1 else 30,
    unit: TimeUnit.CALENDAR_DAYS,
    action: "Serve 30/60-day notice to terminate tenancy."
}

Quick Reference Table

Action Code Section Days Type
Tenant Response CCP § 1167 10 Court Days
3-Day Pay-or-Quit CCP § 1161(2) 3 Calendar Days
Cure Covenant Notice CCP § 1161(3) 3 Calendar Days
Termination (Month-to-Month) Civ. Code § 1946 30/60 Calendar Days
Discovery Cutoff CCP § 2024.040(b)(1) 5 Court Days
Motion Hearings AB 2347 7 Court Days

Implementation Recommendation-How to put UD-DSL to work

A. Python

  • Use 'datetime' and holidays libraries to model court days.
  • Create classes for Notice, Response, and Motion with methods to compute deadlines:
python
class UnlawfulDetainer:
    def __init__(self, start_date):
        self.start_date = start_date
        self.holidays = load_california_holidays()

    def add_court_days(self, days):
        # Logic to skip weekends/holidays
        return computed_date

B. Answer Set Programming (ASP)

  • Model deadlines as predicates for logical reasoning:
asp
% Define court days
court_day(D) :- not weekend(D), not holiday(D).

% Tenant response deadline
response_deadline(D) :- ud_filed(F), D = F + 10 { court_day(D) }.
  • Use ASP solvers like clingo to validate timelines.

C. Z3 (Formal Verification)

  • Encode deadlines as constraints for SMT solvers:
python
from z3 import *
def add_court_days(solver, start, days):
    # Z3 constraints to skip weekends/holidays
    pass

Implementation Notes

1. Holiday Handling

  • Use the holidays Python library with California-specific judicial holidays
  • Example holidays to exclude:
    • New Year's Day (January 1)
    • Thanksgiving (4th Thursday in November)
    • Christmas Day (December 25)

2. Edge Cases

  • Calendar Day Extensions: If a deadline falls on a weekend/holiday, extend it to the next court day.
    def extend_calendar_deadline(date: datetime) -> datetime:
        while date.weekday() >= 5 or date in CA_HOLIDAYS:
            date += timedelta(days=1)
        return date
    
    

Testing

Validate against real-world scenarios: A 3-day notice served on 2025-01-01 (New Year’s Day) should return 2025-01-06. Tenant responses spanning Thanksgiving should skip the holiday.