Skip to content

Commit 0ecbb6d

Browse files
sfbaytidesclaude
andcommitted
Improve P2025 stance detection with common bill language keywords
- Add progressive_keywords for common state legislation language (reproductive health, climate action, immigrant protection, etc.) - Add conservative_keywords for P2025-aligned legislation - Improve impact detection with high_impact_keywords - Better matching for actual bill title language vs formal policy terms Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 1eb6433 commit 0ecbb6d

File tree

1 file changed

+40
-3
lines changed

1 file changed

+40
-3
lines changed

src/civitas/api/routers/states.py

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,34 @@ def classify_bill(text: str) -> tuple[str | None, str | None, str | None, str |
115115
best_score = 0
116116
stance = None
117117

118+
# Additional keywords that typically indicate opposition to P2025 agenda
119+
# These match common progressive state legislation language
120+
progressive_keywords = [
121+
"reproductive health", "reproductive rights", "abortion access",
122+
"climate action", "climate change", "climate resilience", "global warming",
123+
"clean energy", "renewable", "emissions reduction",
124+
"immigrant protection", "immigrant rights", "sanctuary",
125+
"voting access", "voter protection", "election security",
126+
"expand medicaid", "healthcare access", "affordable care",
127+
"gun safety", "firearm regulation", "assault weapon",
128+
"worker protection", "minimum wage increase", "labor rights",
129+
"lgbtq", "gender affirming", "anti-discrimination",
130+
"police accountability", "criminal justice reform",
131+
"tenant protection", "affordable housing", "rent control",
132+
"environmental justice", "environmental protection",
133+
]
134+
135+
# Keywords that typically indicate support for P2025 agenda
136+
conservative_keywords = [
137+
"parental rights", "school choice", "voucher",
138+
"religious liberty", "religious freedom",
139+
"second amendment", "gun rights", "constitutional carry",
140+
"border security", "illegal immigration", "deportation",
141+
"election integrity", "voter id", "citizenship verification",
142+
"reduce regulations", "deregulation",
143+
"protect life", "pro-life", "unborn",
144+
]
145+
118146
for category in P2025_CATEGORIES:
119147
score = sum(1 for kw in category.keywords if kw.lower() in text_lower)
120148
if score > best_score:
@@ -130,17 +158,26 @@ def classify_bill(text: str) -> tuple[str | None, str | None, str | None, str |
130158
):
131159
stance = "oppose"
132160

161+
# Additional stance detection using common bill language
162+
if stance is None:
163+
if any(kw in text_lower for kw in progressive_keywords):
164+
stance = "oppose"
165+
elif any(kw in text_lower for kw in conservative_keywords):
166+
stance = "support"
167+
133168
if best_score == 0:
134169
return None, None, None, None
135170

136171
if stance is None:
137172
stance = "neutral"
138173

139-
# Determine impact based on keyword matches
174+
# Determine impact based on keyword matches and key legislation indicators
140175
impact = "medium" # Default
141-
if best_score >= 5:
176+
high_impact_keywords = ["constitutional", "fundamental", "statewide", "emergency",
177+
"comprehensive", "historic", "landmark", "major reform"]
178+
if best_score >= 4 or any(kw in text_lower for kw in high_impact_keywords):
142179
impact = "high"
143-
elif best_score <= 2:
180+
elif best_score <= 1:
144181
impact = "low"
145182

146183
# Determine scope based on content keywords

0 commit comments

Comments
 (0)