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:
- Tenant responses to UD complaints (
CCP § 1167
). - Hearings on motions/demurrers (
AB 2347
). - Discovery deadlines (
CCP § 2024.040(b)(1)
).
Calendar Days
Include all days (extend deadlines if they fall on non-court days). Used for:
- Landlord notices (3-day pay-or-quit,
CCP § 1161
). - Termination notices (30/60 days,
Civ. Code §§ 1946, 1946.1
). - 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
, andMotion
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.